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 long, if found, 0
89 ftp_expected_bytes (const char *s)
95 while (*s && *s != '(')
99 for (++s; *s && ISSPACE (*s); s++);
107 res = (*s - '0') + 10 * res;
110 while (*s && ISDIGIT (*s));
113 while (*s && ISSPACE (*s))
117 if (TOLOWER (*s) != 'b')
119 if (strncasecmp (s, "byte", 4))
129 * This function sets up a passive data connection with the FTP server.
130 * It is merely a wrapper around ftp_epsv, ftp_lpsv and ftp_pasv.
133 ftp_do_pasv (int csock, ip_address *addr, int *port)
137 /* We need to determine the address family and need to call
138 getpeername, so while we're at it, store the address to ADDR.
139 ftp_pasv and ftp_lpsv can simply override it. */
140 if (!socket_ip_address (csock, addr, ENDPOINT_PEER))
143 /* If our control connection is over IPv6, then we first try EPSV and then
144 * LPSV if the former is not supported. If the control connection is over
145 * IPv4, we simply issue the good old PASV request. */
149 if (!opt.server_response)
150 logputs (LOG_VERBOSE, "==> PASV ... ");
151 err = ftp_pasv (csock, addr, port);
154 if (!opt.server_response)
155 logputs (LOG_VERBOSE, "==> EPSV ... ");
156 err = ftp_epsv (csock, addr, port);
158 /* If EPSV is not supported try LPSV */
159 if (err == FTPNOPASV)
161 if (!opt.server_response)
162 logputs (LOG_VERBOSE, "==> LPSV ... ");
163 err = ftp_lpsv (csock, addr, port);
174 * This function sets up an active data connection with the FTP server.
175 * It is merely a wrapper around ftp_eprt, ftp_lprt and ftp_port.
178 ftp_do_port (int csock, int *local_sock)
183 if (!socket_ip_address (csock, &cip, ENDPOINT_PEER))
186 /* If our control connection is over IPv6, then we first try EPRT and then
187 * LPRT if the former is not supported. If the control connection is over
188 * IPv4, we simply issue the good old PORT request. */
192 if (!opt.server_response)
193 logputs (LOG_VERBOSE, "==> PORT ... ");
194 err = ftp_port (csock, local_sock);
197 if (!opt.server_response)
198 logputs (LOG_VERBOSE, "==> EPRT ... ");
199 err = ftp_eprt (csock, local_sock);
201 /* If EPRT is not supported try LPRT */
202 if (err == FTPPORTERR)
204 if (!opt.server_response)
205 logputs (LOG_VERBOSE, "==> LPRT ... ");
206 err = ftp_lprt (csock, local_sock);
217 ftp_do_pasv (int csock, ip_address *addr, int *port)
219 if (!opt.server_response)
220 logputs (LOG_VERBOSE, "==> PASV ... ");
221 return ftp_pasv (csock, addr, port);
225 ftp_do_port (int csock, int *local_sock)
227 if (!opt.server_response)
228 logputs (LOG_VERBOSE, "==> PORT ... ");
229 return ftp_port (csock, local_sock);
233 /* Retrieves a file with denoted parameters through opening an FTP
234 connection to the server. It always closes the data connection,
235 and closes the control connection in case of error. */
237 getftp (struct url *u, long *len, long restval, ccon *con)
239 int csock, dtsock, local_sock, res;
242 char *user, *passwd, *respline;
245 int pasv_mode_open = 0;
246 long expected_bytes = 0L;
250 assert (con != NULL);
251 assert (con->target != NULL);
253 /* Debug-check of the sanity of the request by making sure that LIST
254 and RETR are never both requested (since we can handle only one
256 assert (!((cmd & DO_LIST) && (cmd & DO_RETR)));
257 /* Make sure that at least *something* is requested. */
258 assert ((cmd & (DO_LIST | DO_CWD | DO_RETR | DO_LOGIN)) != 0);
262 search_netrc (u->host, (const char **)&user, (const char **)&passwd, 1);
263 user = user ? user : opt.ftp_acc;
264 passwd = passwd ? passwd : opt.ftp_pass;
265 assert (user && passwd);
271 if (!(cmd & DO_LOGIN))
273 else /* cmd & DO_LOGIN */
276 char *host = con->proxy ? con->proxy->host : u->host;
277 int port = con->proxy ? con->proxy->port : u->port;
278 char *logname = user;
282 /* If proxy is in use, log in as username@target-site. */
283 logname = xmalloc (strlen (user) + 1 + strlen (u->host) + 1);
284 sprintf (logname, "%s@%s", user, u->host);
287 /* Login to the server: */
289 /* First: Establish the control connection. */
291 csock = connect_to_host (host, port);
295 return (retryable_socket_connect_error (errno)
296 ? CONERROR : CONIMPOSSIBLE);
298 if (cmd & LEAVE_PENDING)
303 /* Second: Login with proper USER/PASS sequence. */
304 logprintf (LOG_VERBOSE, _("Logging in as %s ... "), user);
305 if (opt.server_response)
306 logputs (LOG_ALWAYS, "\n");
307 err = ftp_login (csock, logname, passwd);
312 /* FTPRERR, FTPSRVERR, WRITEFAILED, FTPLOGREFUSED, FTPLOGINC */
316 logputs (LOG_VERBOSE, "\n");
317 logputs (LOG_NOTQUIET, _("\
318 Error in server response, closing control connection.\n"));
324 logputs (LOG_VERBOSE, "\n");
325 logputs (LOG_NOTQUIET, _("Error in server greeting.\n"));
331 logputs (LOG_VERBOSE, "\n");
332 logputs (LOG_NOTQUIET,
333 _("Write failed, closing control connection.\n"));
339 logputs (LOG_VERBOSE, "\n");
340 logputs (LOG_NOTQUIET, _("The server refuses login.\n"));
343 return FTPLOGREFUSED;
346 logputs (LOG_VERBOSE, "\n");
347 logputs (LOG_NOTQUIET, _("Login incorrect.\n"));
353 if (!opt.server_response)
354 logputs (LOG_VERBOSE, _("Logged in!\n"));
361 /* Third: Get the system type */
362 if (!opt.server_response)
363 logprintf (LOG_VERBOSE, "==> SYST ... ");
364 err = ftp_syst (csock, &con->rs);
369 logputs (LOG_VERBOSE, "\n");
370 logputs (LOG_NOTQUIET, _("\
371 Error in server response, closing control connection.\n"));
377 logputs (LOG_VERBOSE, "\n");
378 logputs (LOG_NOTQUIET,
379 _("Server error, can't determine system type.\n"));
382 /* Everything is OK. */
388 if (!opt.server_response && err != FTPSRVERR)
389 logputs (LOG_VERBOSE, _("done. "));
391 /* Fourth: Find the initial ftp directory */
393 if (!opt.server_response)
394 logprintf (LOG_VERBOSE, "==> PWD ... ");
395 err = ftp_pwd (csock, &con->id);
400 logputs (LOG_VERBOSE, "\n");
401 logputs (LOG_NOTQUIET, _("\
402 Error in server response, closing control connection.\n"));
408 /* PWD unsupported -- assume "/". */
409 xfree_null (con->id);
410 con->id = xstrdup ("/");
413 /* Everything is OK. */
419 /* VMS will report something like "PUB$DEVICE:[INITIAL.FOLDER]".
420 Convert it to "/INITIAL/FOLDER" */
421 if (con->rs == ST_VMS)
423 char *path = strchr (con->id, '[');
424 char *pathend = path ? strchr (path + 1, ']') : NULL;
425 if (!path || !pathend)
426 DEBUGP (("Initial VMS directory not in the form [...]!\n"));
429 char *idir = con->id;
430 DEBUGP (("Preprocessing the initial VMS directory\n"));
431 DEBUGP ((" old = '%s'\n", con->id));
432 /* We do the conversion in-place by copying the stuff
433 between [ and ] to the beginning, and changing dots
434 to slashes at the same time. */
436 for (++path; path < pathend; path++, idir++)
437 *idir = *path == '.' ? '/' : *path;
439 DEBUGP ((" new = '%s'\n\n", con->id));
442 if (!opt.server_response)
443 logputs (LOG_VERBOSE, _("done.\n"));
445 /* Fifth: Set the FTP type. */
446 type_char = ftp_process_type (u->params);
447 if (!opt.server_response)
448 logprintf (LOG_VERBOSE, "==> TYPE %c ... ", type_char);
449 err = ftp_type (csock, type_char);
450 /* FTPRERR, WRITEFAILED, FTPUNKNOWNTYPE */
454 logputs (LOG_VERBOSE, "\n");
455 logputs (LOG_NOTQUIET, _("\
456 Error in server response, closing control connection.\n"));
462 logputs (LOG_VERBOSE, "\n");
463 logputs (LOG_NOTQUIET,
464 _("Write failed, closing control connection.\n"));
470 logputs (LOG_VERBOSE, "\n");
471 logprintf (LOG_NOTQUIET,
472 _("Unknown type `%c', closing control connection.\n"),
478 /* Everything is OK. */
484 if (!opt.server_response)
485 logputs (LOG_VERBOSE, _("done. "));
491 logputs (LOG_VERBOSE, _("==> CWD not needed.\n"));
494 char *target = u->dir;
496 DEBUGP (("changing working directory\n"));
498 /* Change working directory. To change to a non-absolute
499 Unix directory, we need to prepend initial directory
500 (con->id) to it. Absolute directories "just work".
502 A relative directory is one that does not begin with '/'
503 and, on non-Unix OS'es, one that doesn't begin with
506 This is not done for OS400, which doesn't use
507 "/"-delimited directories, nor does it support directory
508 hierarchies. "CWD foo" followed by "CWD bar" leaves us
509 in "bar", not in "foo/bar", as would be customary
513 && !(con->rs != ST_UNIX
514 && ISALPHA (target[0])
516 && con->rs != ST_OS400)
518 int idlen = strlen (con->id);
521 /* Strip trailing slash(es) from con->id. */
522 while (idlen > 0 && con->id[idlen - 1] == '/')
524 p = ntarget = (char *)alloca (idlen + 1 + strlen (u->dir) + 1);
525 memcpy (p, con->id, idlen);
530 DEBUGP (("Prepended initial PWD to relative path:\n"));
531 DEBUGP ((" pwd: '%s'\n old: '%s'\n new: '%s'\n",
532 con->id, target, ntarget));
536 /* If the FTP host runs VMS, we will have to convert the absolute
537 directory path in UNIX notation to absolute directory path in
538 VMS notation as VMS FTP servers do not like UNIX notation of
539 absolute paths. "VMS notation" is [dir.subdir.subsubdir]. */
541 if (con->rs == ST_VMS)
544 char *ntarget = (char *)alloca (strlen (target) + 2);
545 /* We use a converted initial dir, so directories in
546 TARGET will be separated with slashes, something like
547 "/INITIAL/FOLDER/DIR/SUBDIR". Convert that to
548 "[INITIAL.FOLDER.DIR.SUBDIR]". */
549 strcpy (ntarget, target);
550 assert (*ntarget == '/');
552 for (tmpp = ntarget + 1; *tmpp; tmpp++)
557 DEBUGP (("Changed file name to VMS syntax:\n"));
558 DEBUGP ((" Unix: '%s'\n VMS: '%s'\n", target, ntarget));
562 if (!opt.server_response)
563 logprintf (LOG_VERBOSE, "==> CWD %s ... ", target);
564 err = ftp_cwd (csock, target);
565 /* FTPRERR, WRITEFAILED, FTPNSFOD */
569 logputs (LOG_VERBOSE, "\n");
570 logputs (LOG_NOTQUIET, _("\
571 Error in server response, closing control connection.\n"));
577 logputs (LOG_VERBOSE, "\n");
578 logputs (LOG_NOTQUIET,
579 _("Write failed, closing control connection.\n"));
585 logputs (LOG_VERBOSE, "\n");
586 logprintf (LOG_NOTQUIET, _("No such directory `%s'.\n\n"),
599 if (!opt.server_response)
600 logputs (LOG_VERBOSE, _("done.\n"));
603 else /* do not CWD */
604 logputs (LOG_VERBOSE, _("==> CWD not required.\n"));
606 if ((cmd & DO_RETR) && restval && *len == 0)
610 if (!opt.server_response)
611 logprintf (LOG_VERBOSE, "==> SIZE %s ... ", u->file);
614 err = ftp_size (csock, u->file, len);
620 logputs (LOG_VERBOSE, "\n");
621 logputs (LOG_NOTQUIET, _("\
622 Error in server response, closing control connection.\n"));
628 /* Everything is OK. */
634 if (!opt.server_response)
635 logputs (LOG_VERBOSE, _("done.\n"));
638 /* If anything is to be retrieved, PORT (or PASV) must be sent. */
639 if (cmd & (DO_LIST | DO_RETR))
641 if (opt.ftp_pasv > 0)
643 ip_address passive_addr;
645 err = ftp_do_pasv (csock, &passive_addr, &passive_port);
646 /* FTPRERR, WRITEFAILED, FTPNOPASV, FTPINVPASV */
650 logputs (LOG_VERBOSE, "\n");
651 logputs (LOG_NOTQUIET, _("\
652 Error in server response, closing control connection.\n"));
658 logputs (LOG_VERBOSE, "\n");
659 logputs (LOG_NOTQUIET,
660 _("Write failed, closing control connection.\n"));
666 logputs (LOG_VERBOSE, "\n");
667 logputs (LOG_NOTQUIET, _("Cannot initiate PASV transfer.\n"));
670 logputs (LOG_VERBOSE, "\n");
671 logputs (LOG_NOTQUIET, _("Cannot parse PASV response.\n"));
682 DEBUGP (("trying to connect to %s port %d\n",
683 pretty_print_address (&passive_addr),
685 dtsock = connect_to_ip (&passive_addr, passive_port, NULL);
688 int save_errno = errno;
691 logprintf (LOG_VERBOSE, _("couldn't connect to %s port %d: %s\n"),
692 pretty_print_address (&passive_addr), passive_port,
693 strerror (save_errno));
694 return (retryable_socket_connect_error (save_errno)
695 ? CONERROR : CONIMPOSSIBLE);
698 pasv_mode_open = 1; /* Flag to avoid accept port */
699 if (!opt.server_response)
700 logputs (LOG_VERBOSE, _("done. "));
704 if (!pasv_mode_open) /* Try to use a port command if PASV failed */
706 err = ftp_do_port (csock, &local_sock);
707 /* FTPRERR, WRITEFAILED, bindport (FTPSYSERR), HOSTERR,
712 logputs (LOG_VERBOSE, "\n");
713 logputs (LOG_NOTQUIET, _("\
714 Error in server response, closing control connection.\n"));
718 fd_close (local_sock);
722 logputs (LOG_VERBOSE, "\n");
723 logputs (LOG_NOTQUIET,
724 _("Write failed, closing control connection.\n"));
728 fd_close (local_sock);
732 logputs (LOG_VERBOSE, "\n");
733 logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
737 fd_close (local_sock);
741 logputs (LOG_VERBOSE, "\n");
742 logprintf (LOG_NOTQUIET, _("Bind error (%s).\n"),
748 logputs (LOG_VERBOSE, "\n");
749 logputs (LOG_NOTQUIET, _("Invalid PORT.\n"));
753 fd_close (local_sock);
763 if (!opt.server_response)
764 logputs (LOG_VERBOSE, _("done. "));
766 } /* cmd & (DO_LIST | DO_RETR) */
768 /* Restart if needed. */
769 if (restval && (cmd & DO_RETR))
771 if (!opt.server_response)
772 logprintf (LOG_VERBOSE, "==> REST %ld ... ", restval);
773 err = ftp_rest (csock, restval);
775 /* FTPRERR, WRITEFAILED, FTPRESTFAIL */
779 logputs (LOG_VERBOSE, "\n");
780 logputs (LOG_NOTQUIET, _("\
781 Error in server response, closing control connection.\n"));
785 fd_close (local_sock);
789 logputs (LOG_VERBOSE, "\n");
790 logputs (LOG_NOTQUIET,
791 _("Write failed, closing control connection.\n"));
795 fd_close (local_sock);
799 logputs (LOG_VERBOSE, _("\nREST failed, starting from scratch.\n"));
809 if (err != FTPRESTFAIL && !opt.server_response)
810 logputs (LOG_VERBOSE, _("done. "));
811 } /* restval && cmd & DO_RETR */
815 /* If we're in spider mode, don't really retrieve anything. The
816 fact that we got to this point should be proof enough that
817 the file exists, vaguely akin to HTTP's concept of a "HEAD"
824 fd_close (local_sock);
830 if (!opt.server_response)
833 logputs (LOG_VERBOSE, "\n");
834 logprintf (LOG_VERBOSE, "==> RETR %s ... ", u->file);
838 err = ftp_retr (csock, u->file);
839 /* FTPRERR, WRITEFAILED, FTPNSFOD */
843 logputs (LOG_VERBOSE, "\n");
844 logputs (LOG_NOTQUIET, _("\
845 Error in server response, closing control connection.\n"));
849 fd_close (local_sock);
853 logputs (LOG_VERBOSE, "\n");
854 logputs (LOG_NOTQUIET,
855 _("Write failed, closing control connection.\n"));
859 fd_close (local_sock);
863 logputs (LOG_VERBOSE, "\n");
864 logprintf (LOG_NOTQUIET, _("No such file `%s'.\n\n"), u->file);
866 fd_close (local_sock);
877 if (!opt.server_response)
878 logputs (LOG_VERBOSE, _("done.\n"));
879 expected_bytes = ftp_expected_bytes (ftp_last_respline);
884 if (!opt.server_response)
885 logputs (LOG_VERBOSE, "==> LIST ... ");
886 /* As Maciej W. Rozycki (macro@ds2.pg.gda.pl) says, `LIST'
887 without arguments is better than `LIST .'; confirmed by
889 err = ftp_list (csock, NULL);
890 /* FTPRERR, WRITEFAILED */
894 logputs (LOG_VERBOSE, "\n");
895 logputs (LOG_NOTQUIET, _("\
896 Error in server response, closing control connection.\n"));
900 fd_close (local_sock);
904 logputs (LOG_VERBOSE, "\n");
905 logputs (LOG_NOTQUIET,
906 _("Write failed, closing control connection.\n"));
910 fd_close (local_sock);
914 logputs (LOG_VERBOSE, "\n");
915 logprintf (LOG_NOTQUIET, _("No such file or directory `%s'.\n\n"),
918 fd_close (local_sock);
928 if (!opt.server_response)
929 logputs (LOG_VERBOSE, _("done.\n"));
930 expected_bytes = ftp_expected_bytes (ftp_last_respline);
931 } /* cmd & DO_LIST */
933 if (!(cmd & (DO_LIST | DO_RETR)) || (opt.spider && !(cmd & DO_LIST)))
936 /* Some FTP servers return the total length of file after REST
937 command, others just return the remaining size. */
938 if (*len && restval && expected_bytes
939 && (expected_bytes == *len - restval))
941 DEBUGP (("Lying FTP server found, adjusting.\n"));
942 expected_bytes = *len;
945 /* If no transmission was required, then everything is OK. */
946 if (!pasv_mode_open) /* we are not using pasive mode so we need
949 /* Wait for the server to connect to the address we're waiting
951 dtsock = accept_connection (local_sock);
954 logprintf (LOG_NOTQUIET, "accept: %s\n", strerror (errno));
959 /* Open the file -- if output_stream is set, use it instead. */
960 if (!output_stream || con->cmd & DO_LIST)
962 mkalldirs (con->target);
964 rotate_backups (con->target);
965 /* #### Is this correct? */
966 chmod (con->target, 0600);
968 fp = fopen (con->target, restval ? "ab" : "wb");
971 logprintf (LOG_NOTQUIET, "%s: %s\n", con->target, strerror (errno));
975 fd_close (local_sock);
984 logprintf (LOG_VERBOSE, _("Length: %s"), legible (*len));
986 logprintf (LOG_VERBOSE, _(" [%s to go]"), legible (*len - restval));
987 logputs (LOG_VERBOSE, "\n");
988 expected_bytes = *len; /* for get_contents/show_progress */
990 else if (expected_bytes)
992 logprintf (LOG_VERBOSE, _("Length: %s"), legible (expected_bytes));
994 logprintf (LOG_VERBOSE, _(" [%s to go]"),
995 legible (expected_bytes - restval));
996 logputs (LOG_VERBOSE, _(" (unauthoritative)\n"));
999 /* Get the contents of the document. */
1001 if (restval && rest_failed)
1002 flags |= rb_skip_startpos;
1003 res = fd_read_body (dtsock, fp,
1004 expected_bytes ? expected_bytes - restval : 0,
1005 restval, len, &con->dltime, flags);
1008 tms = time_str (NULL);
1009 tmrate = retr_rate (*len - restval, con->dltime, 0);
1010 /* Close data connection socket. */
1012 fd_close (local_sock);
1013 /* Close the local file. */
1015 /* Close or flush the file. We have to be careful to check for
1016 error here. Checking the result of fwrite() is not enough --
1017 errors could go unnoticed! */
1019 if (!output_stream || con->cmd & DO_LIST)
1020 flush_res = fclose (fp);
1022 flush_res = fflush (fp);
1023 if (flush_res == EOF)
1027 /* If get_contents couldn't write to fp, bail out. */
1030 logprintf (LOG_NOTQUIET, _("%s: %s, closing control connection.\n"),
1031 con->target, strerror (errno));
1038 logprintf (LOG_NOTQUIET, _("%s (%s) - Data connection: %s; "),
1039 tms, tmrate, strerror (errno));
1040 if (opt.server_response)
1041 logputs (LOG_ALWAYS, "\n");
1044 /* Get the server to tell us if everything is retrieved. */
1045 err = ftp_response (csock, &respline);
1049 /* The control connection is decidedly closed. Print the time
1050 only if it hasn't already been printed. */
1052 logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
1053 logputs (LOG_NOTQUIET, _("Control connection closed.\n"));
1054 /* If there is an error on the control connection, close it, but
1055 return FTPRETRINT, since there is a possibility that the
1056 whole file was retrieved nevertheless (but that is for
1057 ftp_loop_internal to decide). */
1061 } /* err != FTPOK */
1062 /* If retrieval failed for any reason, return FTPRETRINT, but do not
1063 close socket, since the control connection is still alive. If
1064 there is something wrong with the control connection, it will
1065 become apparent later. */
1066 if (*respline != '2')
1070 logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
1071 logputs (LOG_NOTQUIET, _("Data transfer aborted.\n"));
1078 /* What now? The data connection was erroneous, whereas the
1079 response says everything is OK. We shall play it safe. */
1083 if (!(cmd & LEAVE_PENDING))
1085 /* Closing the socket is faster than sending 'QUIT' and the
1086 effect is the same. */
1090 /* If it was a listing, and opt.server_response is true,
1092 if (opt.server_response && (con->cmd & DO_LIST))
1094 mkalldirs (con->target);
1095 fp = fopen (con->target, "r");
1097 logprintf (LOG_ALWAYS, "%s: %s\n", con->target, strerror (errno));
1101 /* The lines are being read with read_whole_line because of
1102 no-buffering on opt.lfile. */
1103 while ((line = read_whole_line (fp)))
1105 logprintf (LOG_ALWAYS, "%s\n", line);
1110 } /* con->cmd & DO_LIST && server_response */
1112 return RETRFINISHED;
1115 /* A one-file FTP loop. This is the part where FTP retrieval is
1116 retried, and retried, and retried, and...
1118 This loop either gets commands from con, or (if ON_YOUR_OWN is
1119 set), makes them up to retrieve the file given by the URL. */
1121 ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
1124 long restval, len = 0;
1126 char *tmrate = NULL;
1131 con->target = url_file_name (u);
1133 if (opt.noclobber && file_exists_p (con->target))
1135 logprintf (LOG_VERBOSE,
1136 _("File `%s' already there, not retrieving.\n"), con->target);
1137 /* If the file is there, we suppose it's retrieved OK. */
1141 /* Remove it if it's a link. */
1142 remove_link (con->target);
1143 if (!opt.output_document)
1146 locf = opt.output_document;
1150 if (con->st & ON_YOUR_OWN)
1151 con->st = ON_YOUR_OWN;
1153 orig_lp = con->cmd & LEAVE_PENDING ? 1 : 0;
1158 /* Increment the pass counter. */
1160 sleep_between_retrievals (count);
1161 if (con->st & ON_YOUR_OWN)
1164 con->cmd |= (DO_RETR | LEAVE_PENDING);
1165 if (con->csock != -1)
1166 con->cmd &= ~ (DO_LOGIN | DO_CWD);
1168 con->cmd |= (DO_LOGIN | DO_CWD);
1170 else /* not on your own */
1172 if (con->csock != -1)
1173 con->cmd &= ~DO_LOGIN;
1175 con->cmd |= DO_LOGIN;
1176 if (con->st & DONE_CWD)
1177 con->cmd &= ~DO_CWD;
1182 /* Decide whether or not to restart. */
1185 restval = len; /* start where the previous run left off */
1186 else if (opt.always_rest
1187 && stat (locf, &st) == 0
1188 && S_ISREG (st.st_mode))
1189 restval = st.st_size;
1191 /* Get the current time string. */
1192 tms = time_str (NULL);
1193 /* Print fetch message, if opt.verbose. */
1196 char *hurl = url_string (u, 1);
1200 sprintf (tmp, _("(try:%2d)"), count);
1201 logprintf (LOG_VERBOSE, "--%s-- %s\n %s => `%s'\n",
1202 tms, hurl, tmp, locf);
1204 ws_changetitle (hurl, 1);
1208 /* Send getftp the proper length, if fileinfo was provided. */
1213 err = getftp (u, &len, restval, con);
1215 if (con->csock != -1)
1216 con->st &= ~DONE_CWD;
1218 con->st |= DONE_CWD;
1222 case HOSTERR: case CONIMPOSSIBLE: case FWRITEERR: case FOPENERR:
1223 case FTPNSFOD: case FTPLOGINC: case FTPNOPASV: case CONTNOTSUPPORTED:
1224 /* Fatal errors, give up. */
1227 case CONSOCKERR: case CONERROR: case FTPSRVERR: case FTPRERR:
1228 case WRITEFAILED: case FTPUNKNOWNTYPE: case FTPSYSERR:
1229 case FTPPORTERR: case FTPLOGREFUSED: case FTPINVPASV:
1230 printwhat (count, opt.ntry);
1231 /* non-fatal errors */
1235 /* If the control connection was closed, the retrieval
1236 will be considered OK if f->size == len. */
1237 if (!f || len != f->size)
1239 printwhat (count, opt.ntry);
1251 tms = time_str (NULL);
1253 tmrate = retr_rate (len - restval, con->dltime, 0);
1255 /* If we get out of the switch above without continue'ing, we've
1256 successfully downloaded a file. Remember this fact. */
1257 downloaded_file (FILE_DOWNLOADED_NORMALLY, locf);
1259 if (con->st & ON_YOUR_OWN)
1261 fd_close (con->csock);
1265 logprintf (LOG_VERBOSE, _("%s (%s) - `%s' saved [%ld]\n\n"),
1266 tms, tmrate, locf, len);
1267 if (!opt.verbose && !opt.quiet)
1269 /* Need to hide the password from the URL. The `if' is here
1270 so that we don't do the needless allocation every
1272 char *hurl = url_string (u, 1);
1273 logprintf (LOG_NONVERBOSE, "%s URL: %s [%ld] -> \"%s\" [%d]\n",
1274 tms, hurl, len, locf, count);
1278 if ((con->cmd & DO_LIST))
1279 /* This is a directory listing file. */
1281 if (!opt.remove_listing)
1282 /* --dont-remove-listing was specified, so do count this towards the
1283 number of bytes and files downloaded. */
1285 total_downloaded_bytes += len;
1289 /* Deletion of listing files is not controlled by --delete-after, but
1290 by the more specific option --dont-remove-listing, and the code
1291 to do this deletion is in another function. */
1293 else if (!opt.spider)
1294 /* This is not a directory listing file. */
1296 /* Unlike directory listing files, don't pretend normal files weren't
1297 downloaded if they're going to be deleted. People seeding proxies,
1298 for instance, may want to know how many bytes and files they've
1299 downloaded through it. */
1300 total_downloaded_bytes += len;
1303 if (opt.delete_after)
1305 DEBUGP (("Removing file due to --delete-after in"
1306 " ftp_loop_internal():\n"));
1307 logprintf (LOG_VERBOSE, _("Removing %s.\n"), locf);
1309 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1313 /* Restore the original leave-pendingness. */
1315 con->cmd |= LEAVE_PENDING;
1317 con->cmd &= ~LEAVE_PENDING;
1319 } while (!opt.ntry || (count < opt.ntry));
1321 if (con->csock != -1 && (con->st & ON_YOUR_OWN))
1323 fd_close (con->csock);
1329 /* Return the directory listing in a reusable format. The directory
1330 is specifed in u->dir. */
1332 ftp_get_listing (struct url *u, ccon *con, struct fileinfo **f)
1335 char *uf; /* url file name */
1336 char *lf; /* list file name */
1337 char *old_target = con->target;
1339 con->st &= ~ON_YOUR_OWN;
1340 con->cmd |= (DO_LIST | LEAVE_PENDING);
1341 con->cmd &= ~DO_RETR;
1343 /* Find the listing file name. We do it by taking the file name of
1344 the URL and replacing the last component with the listing file
1346 uf = url_file_name (u);
1347 lf = file_merge (uf, LIST_FILENAME);
1349 DEBUGP ((_("Using `%s' as listing tmp file.\n"), lf));
1352 err = ftp_loop_internal (u, NULL, con);
1353 con->target = old_target;
1356 *f = ftp_parse_ls (lf, con->rs);
1359 if (opt.remove_listing)
1362 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1364 logprintf (LOG_VERBOSE, _("Removed `%s'.\n"), lf);
1367 con->cmd &= ~DO_LIST;
1371 static uerr_t ftp_retrieve_dirs PARAMS ((struct url *, struct fileinfo *,
1373 static uerr_t ftp_retrieve_glob PARAMS ((struct url *, ccon *, int));
1374 static struct fileinfo *delelement PARAMS ((struct fileinfo *,
1375 struct fileinfo **));
1376 static void freefileinfo PARAMS ((struct fileinfo *f));
1378 /* Retrieve a list of files given in struct fileinfo linked list. If
1379 a file is a symbolic link, do not retrieve it, but rather try to
1380 set up a similar link on the local disk, if the symlinks are
1383 If opt.recursive is set, after all files have been retrieved,
1384 ftp_retrieve_dirs will be called to retrieve the directories. */
1386 ftp_retrieve_list (struct url *u, struct fileinfo *f, ccon *con)
1388 static int depth = 0;
1390 struct fileinfo *orig;
1395 /* Increase the depth. */
1397 if (opt.reclevel != INFINITE_RECURSION && depth > opt.reclevel)
1399 DEBUGP ((_("Recursion depth %d exceeded max. depth %d.\n"),
1400 depth, opt.reclevel));
1408 con->st &= ~ON_YOUR_OWN;
1409 if (!(con->st & DONE_CWD))
1412 con->cmd &= ~DO_CWD;
1413 con->cmd |= (DO_RETR | LEAVE_PENDING);
1416 con->cmd |= DO_LOGIN;
1418 con->cmd &= ~DO_LOGIN;
1420 err = RETROK; /* in case it's not used */
1424 char *old_target, *ofile;
1426 if (opt.quota && total_downloaded_bytes > opt.quota)
1431 old_target = con->target;
1433 ofile = xstrdup (u->file);
1434 url_set_file (u, f->name);
1436 con->target = url_file_name (u);
1440 if (opt.timestamping && f->type == FT_PLAINFILE)
1443 /* If conversion of HTML files retrieved via FTP is ever implemented,
1444 we'll need to stat() <file>.orig here when -K has been specified.
1445 I'm not implementing it now since files on an FTP server are much
1446 more likely than files on an HTTP server to legitimately have a
1448 if (!stat (con->target, &st))
1452 /* Else, get it from the file. */
1453 local_size = st.st_size;
1456 /* Modification time granularity is 2 seconds for Windows, so
1457 increase local time by 1 second for later comparison. */
1460 /* Compare file sizes only for servers that tell us correct
1461 values. Assumme sizes being equal for servers that lie
1463 cor_val = (con->rs == ST_UNIX || con->rs == ST_WINNT);
1464 eq_size = cor_val ? (local_size == f->size) : 1 ;
1465 if (f->tstamp <= tml && eq_size)
1467 /* Remote file is older, file sizes can be compared and
1469 logprintf (LOG_VERBOSE, _("\
1470 Remote file no newer than local file `%s' -- not retrieving.\n"), con->target);
1475 /* Remote file is newer or sizes cannot be matched */
1476 logprintf (LOG_VERBOSE, _("\
1477 Remote file is newer than local file `%s' -- retrieving.\n\n"),
1482 /* Sizes do not match */
1483 logprintf (LOG_VERBOSE, _("\
1484 The sizes do not match (local %ld) -- retrieving.\n\n"), local_size);
1487 } /* opt.timestamping && f->type == FT_PLAINFILE */
1491 /* If opt.retr_symlinks is defined, we treat symlinks as
1492 if they were normal files. There is currently no way
1493 to distinguish whether they might be directories, and
1495 if (!opt.retr_symlinks)
1499 logputs (LOG_NOTQUIET,
1500 _("Invalid name of the symlink, skipping.\n"));
1504 /* Check whether we already have the correct
1506 int rc = lstat (con->target, &st);
1509 size_t len = strlen (f->linkto) + 1;
1510 if (S_ISLNK (st.st_mode))
1512 char *link_target = (char *)alloca (len);
1513 size_t n = readlink (con->target, link_target, len);
1515 && (memcmp (link_target, f->linkto, n) == 0))
1517 logprintf (LOG_VERBOSE, _("\
1518 Already have correct symlink %s -> %s\n\n"),
1519 con->target, f->linkto);
1525 logprintf (LOG_VERBOSE, _("Creating symlink %s -> %s\n"),
1526 con->target, f->linkto);
1527 /* Unlink before creating symlink! */
1528 unlink (con->target);
1529 if (symlink (f->linkto, con->target) == -1)
1530 logprintf (LOG_NOTQUIET, "symlink: %s\n",
1532 logputs (LOG_VERBOSE, "\n");
1533 } /* have f->linkto */
1534 #else /* not HAVE_SYMLINK */
1535 logprintf (LOG_NOTQUIET,
1536 _("Symlinks not supported, skipping symlink `%s'.\n"),
1538 #endif /* not HAVE_SYMLINK */
1540 else /* opt.retr_symlinks */
1543 err = ftp_loop_internal (u, f, con);
1544 } /* opt.retr_symlinks */
1548 logprintf (LOG_NOTQUIET, _("Skipping directory `%s'.\n"),
1552 /* Call the retrieve loop. */
1554 err = ftp_loop_internal (u, f, con);
1557 logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
1562 /* Set the time-stamp information to the local file. Symlinks
1563 are not to be stamped because it sets the stamp on the
1565 if (!(f->type == FT_SYMLINK && !opt.retr_symlinks)
1568 && file_exists_p (con->target))
1570 /* #### This code repeats in http.c and ftp.c. Move it to a
1572 const char *fl = NULL;
1573 if (opt.output_document)
1575 if (output_stream_regular)
1576 fl = opt.output_document;
1581 touch (fl, f->tstamp);
1583 else if (f->tstamp == -1)
1584 logprintf (LOG_NOTQUIET, _("%s: corrupt time-stamp.\n"), con->target);
1586 if (f->perms && f->type == FT_PLAINFILE && dlthis)
1588 if (opt.preserve_perm)
1589 chmod (con->target, f->perms);
1592 DEBUGP (("Unrecognized permissions for %s.\n", con->target));
1594 xfree (con->target);
1595 con->target = old_target;
1597 url_set_file (u, ofile);
1600 /* Break on fatals. */
1601 if (err == QUOTEXC || err == HOSTERR || err == FWRITEERR)
1603 con->cmd &= ~ (DO_CWD | DO_LOGIN);
1607 /* We do not want to call ftp_retrieve_dirs here */
1608 if (opt.recursive &&
1609 !(opt.reclevel != INFINITE_RECURSION && depth >= opt.reclevel))
1610 err = ftp_retrieve_dirs (u, orig, con);
1611 else if (opt.recursive)
1612 DEBUGP ((_("Will not retrieve dirs since depth is %d (max %d).\n"),
1613 depth, opt.reclevel));
1618 /* Retrieve the directories given in a file list. This function works
1619 by simply going through the linked list and calling
1620 ftp_retrieve_glob on each directory entry. The function knows
1621 about excluded directories. */
1623 ftp_retrieve_dirs (struct url *u, struct fileinfo *f, ccon *con)
1625 char *container = NULL;
1626 int container_size = 0;
1628 for (; f; f = f->next)
1631 char *odir, *newdir;
1633 if (opt.quota && total_downloaded_bytes > opt.quota)
1635 if (f->type != FT_DIRECTORY)
1638 /* Allocate u->dir off stack, but reallocate only if a larger
1639 string is needed. It's a pity there's no "realloca" for an
1640 item on the bottom of the stack. */
1641 size = strlen (u->dir) + 1 + strlen (f->name) + 1;
1642 if (size > container_size)
1643 container = (char *)alloca (size);
1648 || (*odir == '/' && *(odir + 1) == '\0'))
1649 /* If ODIR is empty or just "/", simply append f->name to
1650 ODIR. (In the former case, to preserve u->dir being
1651 relative; in the latter case, to avoid double slash.) */
1652 sprintf (newdir, "%s%s", odir, f->name);
1654 /* Else, use a separator. */
1655 sprintf (newdir, "%s/%s", odir, f->name);
1657 DEBUGP (("Composing new CWD relative to the initial directory.\n"));
1658 DEBUGP ((" odir = '%s'\n f->name = '%s'\n newdir = '%s'\n\n",
1659 odir, f->name, newdir));
1660 if (!accdir (newdir, ALLABS))
1662 logprintf (LOG_VERBOSE, _("\
1663 Not descending to `%s' as it is excluded/not-included.\n"), newdir);
1667 con->st &= ~DONE_CWD;
1669 odir = xstrdup (u->dir); /* because url_set_dir will free
1671 url_set_dir (u, newdir);
1672 ftp_retrieve_glob (u, con, GETALL);
1673 url_set_dir (u, odir);
1676 /* Set the time-stamp? */
1679 if (opt.quota && total_downloaded_bytes > opt.quota)
1685 /* Return non-zero if S has a leading '/' or contains '../' */
1687 has_insecure_name_p (const char *s)
1692 if (strstr (s, "../") != 0)
1698 /* A near-top-level function to retrieve the files in a directory.
1699 The function calls ftp_get_listing, to get a linked list of files.
1700 Then it weeds out the file names that do not match the pattern.
1701 ftp_retrieve_list is called with this updated list as an argument.
1703 If the argument ACTION is GETONE, just download the file (but first
1704 get the listing, so that the time-stamp is heeded); if it's GLOBALL,
1705 use globbing; if it's GETALL, download the whole directory. */
1707 ftp_retrieve_glob (struct url *u, ccon *con, int action)
1709 struct fileinfo *f, *start;
1712 con->cmd |= LEAVE_PENDING;
1714 res = ftp_get_listing (u, con, &start);
1717 /* First: weed out that do not conform the global rules given in
1718 opt.accepts and opt.rejects. */
1719 if (opt.accepts || opt.rejects)
1724 if (f->type != FT_DIRECTORY && !acceptable (f->name))
1726 logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"), f->name);
1727 f = delelement (f, &start);
1733 /* Remove all files with possible harmful names */
1737 if (has_insecure_name_p (f->name))
1739 logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"), f->name);
1740 f = delelement (f, &start);
1745 /* Now weed out the files that do not match our globbing pattern.
1746 If we are dealing with a globbing pattern, that is. */
1747 if (*u->file && (action == GLOBALL || action == GETONE))
1754 matchres = fnmatch (u->file, f->name, 0);
1757 logprintf (LOG_NOTQUIET, "%s: %s\n", con->target,
1761 if (matchres == FNM_NOMATCH)
1762 f = delelement (f, &start); /* delete the element from the list */
1764 f = f->next; /* leave the element in the list */
1768 freefileinfo (start);
1769 return RETRBADPATTERN;
1775 /* Just get everything. */
1776 ftp_retrieve_list (u, start, con);
1780 if (action == GLOBALL)
1783 /* #### This message SUCKS. We should see what was the
1784 reason that nothing was retrieved. */
1785 logprintf (LOG_VERBOSE, _("No matches on pattern `%s'.\n"), u->file);
1787 else /* GETONE or GETALL */
1789 /* Let's try retrieving it anyway. */
1790 con->st |= ON_YOUR_OWN;
1791 res = ftp_loop_internal (u, NULL, con);
1795 freefileinfo (start);
1796 if (opt.quota && total_downloaded_bytes > opt.quota)
1799 /* #### Should we return `res' here? */
1803 /* The wrapper that calls an appropriate routine according to contents
1804 of URL. Inherently, its capabilities are limited on what can be
1805 encoded into a URL. */
1807 ftp_loop (struct url *u, int *dt, struct url *proxy)
1809 ccon con; /* FTP connection */
1814 memset (&con, 0, sizeof (con));
1817 con.st = ON_YOUR_OWN;
1821 res = RETROK; /* in case it's not used */
1823 /* If the file name is empty, the user probably wants a directory
1824 index. We'll provide one, properly HTML-ized. Unless
1825 opt.htmlify is 0, of course. :-) */
1826 if (!*u->file && !opt.recursive)
1829 res = ftp_get_listing (u, &con, &f);
1833 if (opt.htmlify && !opt.spider)
1835 char *filename = (opt.output_document
1836 ? xstrdup (opt.output_document)
1837 : (con.target ? xstrdup (con.target)
1838 : url_file_name (u)));
1839 res = ftp_index (filename, u, f);
1840 if (res == FTPOK && opt.verbose)
1842 if (!opt.output_document)
1846 if (stat (filename, &st) == 0)
1850 logprintf (LOG_NOTQUIET,
1851 _("Wrote HTML-ized index to `%s' [%ld].\n"),
1855 logprintf (LOG_NOTQUIET,
1856 _("Wrote HTML-ized index to `%s'.\n"),
1866 int wild = has_wildcards_p (u->file);
1867 if ((opt.ftp_glob && wild) || opt.recursive || opt.timestamping)
1869 /* ftp_retrieve_glob is a catch-all function that gets called
1870 if we need globbing, time-stamping or recursion. Its
1871 third argument is just what we really need. */
1872 res = ftp_retrieve_glob (u, &con,
1873 (opt.ftp_glob && wild) ? GLOBALL : GETONE);
1876 res = ftp_loop_internal (u, NULL, &con);
1882 /* If a connection was left, quench it. */
1883 if (con.csock != -1)
1884 fd_close (con.csock);
1885 xfree_null (con.id);
1887 xfree_null (con.target);
1892 /* Delete an element from the fileinfo linked list. Returns the
1893 address of the next element, or NULL if the list is exhausted. It
1894 can modify the start of the list. */
1895 static struct fileinfo *
1896 delelement (struct fileinfo *f, struct fileinfo **start)
1898 struct fileinfo *prev = f->prev;
1899 struct fileinfo *next = f->next;
1902 xfree_null (f->linkto);
1914 /* Free the fileinfo linked list of files. */
1916 freefileinfo (struct fileinfo *f)
1920 struct fileinfo *next = f->next;