1 /* File Transfer Protocol support.
2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
5 This file is part of GNU Wget.
7 GNU Wget is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 GNU Wget is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Wget. If not, see <http://www.gnu.org/licenses/>.
20 Additional permission under GNU GPL version 3 section 7
22 If you modify this program, or any covered work, by linking or
23 combining it with the OpenSSL project's OpenSSL library (or a
24 modified version of that library), containing parts covered by the
25 terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
26 grants you additional permission to convey the resulting work.
27 Corresponding Source for a non-source form of such a combination
28 shall include the source code for the parts of OpenSSL used as well
29 as that of the covered work. */
50 #include "convert.h" /* for downloaded_file */
51 #include "recur.h" /* for INFINITE_RECURSION */
55 #endif /* def __VMS */
58 /* File where the "ls -al" listing will be saved. */
60 #define LIST_FILENAME "_listing"
62 #define LIST_FILENAME ".listing"
67 int st; /* connection status */
68 int cmd; /* command code */
69 int csock; /* control connection socket */
70 double dltime; /* time of the download in msecs */
71 enum stype rs; /* remote system reported by ftp server */
72 char *id; /* initial directory */
73 char *target; /* target file name */
74 struct url *proxy; /* FTWK-style proxy */
79 /* Look for regexp "( *[0-9]+ *byte" (literal parenthesis) anywhere in
80 the string S, and return the number converted to wgint, if found, 0
83 ftp_expected_bytes (const char *s)
89 while (*s && *s != '(')
93 ++s; /* skip the '(' */
94 res = str_to_wgint (s, (char **) &s, 10);
97 while (*s && c_isspace (*s))
101 if (c_tolower (*s) != 'b')
103 if (strncasecmp (s, "byte", 4))
113 * This function sets up a passive data connection with the FTP server.
114 * It is merely a wrapper around ftp_epsv, ftp_lpsv and ftp_pasv.
117 ftp_do_pasv (int csock, ip_address *addr, int *port)
121 /* We need to determine the address family and need to call
122 getpeername, so while we're at it, store the address to ADDR.
123 ftp_pasv and ftp_lpsv can simply override it. */
124 if (!socket_ip_address (csock, addr, ENDPOINT_PEER))
127 /* If our control connection is over IPv6, then we first try EPSV and then
128 * LPSV if the former is not supported. If the control connection is over
129 * IPv4, we simply issue the good old PASV request. */
130 switch (addr->family)
133 if (!opt.server_response)
134 logputs (LOG_VERBOSE, "==> PASV ... ");
135 err = ftp_pasv (csock, addr, port);
138 if (!opt.server_response)
139 logputs (LOG_VERBOSE, "==> EPSV ... ");
140 err = ftp_epsv (csock, addr, port);
142 /* If EPSV is not supported try LPSV */
143 if (err == FTPNOPASV)
145 if (!opt.server_response)
146 logputs (LOG_VERBOSE, "==> LPSV ... ");
147 err = ftp_lpsv (csock, addr, port);
158 * This function sets up an active data connection with the FTP server.
159 * It is merely a wrapper around ftp_eprt, ftp_lprt and ftp_port.
162 ftp_do_port (int csock, int *local_sock)
167 if (!socket_ip_address (csock, &cip, ENDPOINT_PEER))
170 /* If our control connection is over IPv6, then we first try EPRT and then
171 * LPRT if the former is not supported. If the control connection is over
172 * IPv4, we simply issue the good old PORT request. */
176 if (!opt.server_response)
177 logputs (LOG_VERBOSE, "==> PORT ... ");
178 err = ftp_port (csock, local_sock);
181 if (!opt.server_response)
182 logputs (LOG_VERBOSE, "==> EPRT ... ");
183 err = ftp_eprt (csock, local_sock);
185 /* If EPRT is not supported try LPRT */
186 if (err == FTPPORTERR)
188 if (!opt.server_response)
189 logputs (LOG_VERBOSE, "==> LPRT ... ");
190 err = ftp_lprt (csock, local_sock);
201 ftp_do_pasv (int csock, ip_address *addr, int *port)
203 if (!opt.server_response)
204 logputs (LOG_VERBOSE, "==> PASV ... ");
205 return ftp_pasv (csock, addr, port);
209 ftp_do_port (int csock, int *local_sock)
211 if (!opt.server_response)
212 logputs (LOG_VERBOSE, "==> PORT ... ");
213 return ftp_port (csock, local_sock);
218 print_length (wgint size, wgint start, bool authoritative)
220 logprintf (LOG_VERBOSE, _("Length: %s"), number_to_static_string (size));
222 logprintf (LOG_VERBOSE, " (%s)", human_readable (size));
225 if (size - start >= 1024)
226 logprintf (LOG_VERBOSE, _(", %s (%s) remaining"),
227 number_to_static_string (size - start),
228 human_readable (size - start));
230 logprintf (LOG_VERBOSE, _(", %s remaining"),
231 number_to_static_string (size - start));
233 logputs (LOG_VERBOSE, !authoritative ? _(" (unauthoritative)\n") : "\n");
236 static uerr_t ftp_get_listing (struct url *, ccon *, struct fileinfo **);
238 /* Retrieves a file with denoted parameters through opening an FTP
239 connection to the server. It always closes the data connection,
240 and closes the control connection in case of error. */
242 getftp (struct url *u, wgint *len, wgint restval, ccon *con)
244 int csock, dtsock, local_sock, res;
245 uerr_t err = RETROK; /* appease the compiler */
247 char *user, *passwd, *respline;
251 bool pasv_mode_open = false;
252 wgint expected_bytes = 0;
253 bool rest_failed = false;
258 assert (con != NULL);
259 assert (con->target != NULL);
261 /* Debug-check of the sanity of the request by making sure that LIST
262 and RETR are never both requested (since we can handle only one
264 assert (!((cmd & DO_LIST) && (cmd & DO_RETR)));
265 /* Make sure that at least *something* is requested. */
266 assert ((cmd & (DO_LIST | DO_CWD | DO_RETR | DO_LOGIN)) != 0);
270 search_netrc (u->host, (const char **)&user, (const char **)&passwd, 1);
271 user = user ? user : (opt.ftp_user ? opt.ftp_user : opt.user);
272 if (!user) user = "anonymous";
273 passwd = passwd ? passwd : (opt.ftp_passwd ? opt.ftp_passwd : opt.passwd);
274 if (!passwd) passwd = "-wget@";
280 if (!(cmd & DO_LOGIN))
282 else /* cmd & DO_LOGIN */
284 char *host = con->proxy ? con->proxy->host : u->host;
285 int port = con->proxy ? con->proxy->port : u->port;
286 char *logname = user;
290 /* If proxy is in use, log in as username@target-site. */
291 logname = concat_strings (user, "@", u->host, (char *) 0);
294 /* Login to the server: */
296 /* First: Establish the control connection. */
298 csock = connect_to_host (host, port);
302 return (retryable_socket_connect_error (errno)
303 ? CONERROR : CONIMPOSSIBLE);
305 if (cmd & LEAVE_PENDING)
310 /* Second: Login with proper USER/PASS sequence. */
311 logprintf (LOG_VERBOSE, _("Logging in as %s ... "),
312 quotearg_style (escape_quoting_style, user));
313 if (opt.server_response)
314 logputs (LOG_ALWAYS, "\n");
315 err = ftp_login (csock, logname, passwd);
320 /* FTPRERR, FTPSRVERR, WRITEFAILED, FTPLOGREFUSED, FTPLOGINC */
324 logputs (LOG_VERBOSE, "\n");
325 logputs (LOG_NOTQUIET, _("\
326 Error in server response, closing control connection.\n"));
331 logputs (LOG_VERBOSE, "\n");
332 logputs (LOG_NOTQUIET, _("Error in server greeting.\n"));
337 logputs (LOG_VERBOSE, "\n");
338 logputs (LOG_NOTQUIET,
339 _("Write failed, closing control connection.\n"));
344 logputs (LOG_VERBOSE, "\n");
345 logputs (LOG_NOTQUIET, _("The server refuses login.\n"));
348 return FTPLOGREFUSED;
350 logputs (LOG_VERBOSE, "\n");
351 logputs (LOG_NOTQUIET, _("Login incorrect.\n"));
356 if (!opt.server_response)
357 logputs (LOG_VERBOSE, _("Logged in!\n"));
362 /* Third: Get the system type */
363 if (!opt.server_response)
364 logprintf (LOG_VERBOSE, "==> SYST ... ");
365 err = ftp_syst (csock, &con->rs);
370 logputs (LOG_VERBOSE, "\n");
371 logputs (LOG_NOTQUIET, _("\
372 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. */
387 if (!opt.server_response && err != FTPSRVERR)
388 logputs (LOG_VERBOSE, _("done. "));
390 /* Fourth: Find the initial ftp directory */
392 if (!opt.server_response)
393 logprintf (LOG_VERBOSE, "==> PWD ... ");
394 err = ftp_pwd (csock, &con->id);
399 logputs (LOG_VERBOSE, "\n");
400 logputs (LOG_NOTQUIET, _("\
401 Error in server response, closing control connection.\n"));
406 /* PWD unsupported -- assume "/". */
407 xfree_null (con->id);
408 con->id = xstrdup ("/");
411 /* Everything is OK. */
419 Don't help me out. Please.
420 A reasonably recent VMS FTP server will cope just fine with
421 UNIX file specifications. This code just spoils things.
422 Discarding the device name, for example, is not a wise move.
423 This code was disabled but left in as an example of what not
427 /* VMS will report something like "PUB$DEVICE:[INITIAL.FOLDER]".
428 Convert it to "/INITIAL/FOLDER" */
429 if (con->rs == ST_VMS)
431 char *path = strchr (con->id, '[');
432 char *pathend = path ? strchr (path + 1, ']') : NULL;
433 if (!path || !pathend)
434 DEBUGP (("Initial VMS directory not in the form [...]!\n"));
437 char *idir = con->id;
438 DEBUGP (("Preprocessing the initial VMS directory\n"));
439 DEBUGP ((" old = '%s'\n", con->id));
440 /* We do the conversion in-place by copying the stuff
441 between [ and ] to the beginning, and changing dots
442 to slashes at the same time. */
444 for (++path; path < pathend; path++, idir++)
445 *idir = *path == '.' ? '/' : *path;
447 DEBUGP ((" new = '%s'\n\n", con->id));
452 if (!opt.server_response)
453 logputs (LOG_VERBOSE, _("done.\n"));
455 /* Fifth: Set the FTP type. */
456 type_char = ftp_process_type (u->params);
457 if (!opt.server_response)
458 logprintf (LOG_VERBOSE, "==> TYPE %c ... ", type_char);
459 err = ftp_type (csock, type_char);
460 /* FTPRERR, WRITEFAILED, FTPUNKNOWNTYPE */
464 logputs (LOG_VERBOSE, "\n");
465 logputs (LOG_NOTQUIET, _("\
466 Error in server response, closing control connection.\n"));
471 logputs (LOG_VERBOSE, "\n");
472 logputs (LOG_NOTQUIET,
473 _("Write failed, closing control connection.\n"));
478 logputs (LOG_VERBOSE, "\n");
479 logprintf (LOG_NOTQUIET,
480 _("Unknown type `%c', closing control connection.\n"),
486 /* Everything is OK. */
491 if (!opt.server_response)
492 logputs (LOG_VERBOSE, _("done. "));
498 logputs (LOG_VERBOSE, _("==> CWD not needed.\n"));
506 char *target = u->dir;
508 DEBUGP (("changing working directory\n"));
510 /* Change working directory. To change to a non-absolute
511 Unix directory, we need to prepend initial directory
512 (con->id) to it. Absolute directories "just work".
514 A relative directory is one that does not begin with '/'
515 and, on non-Unix OS'es, one that doesn't begin with
518 This is not done for OS400, which doesn't use
519 "/"-delimited directories, nor does it support directory
520 hierarchies. "CWD foo" followed by "CWD bar" leaves us
521 in "bar", not in "foo/bar", as would be customary
525 Why is this wise even on UNIX? It certainly fouls VMS.
526 See below for a more reliable, more universal method.
530 I'm not crazy about it either. I'm informed it's useful
531 for misconfigured servers that have some dirs in the path
532 with +x but -r, but this method is not RFC-conformant. I
533 understand the need to deal with crappy server
534 configurations, but it's far better to use the canonical
535 method first, and fall back to kludges second.
539 && !(con->rs != ST_UNIX
540 && c_isalpha (target[0])
542 && (con->rs != ST_OS400)
543 && (con->rs != ST_VMS))
545 int idlen = strlen (con->id);
548 /* Strip trailing slash(es) from con->id. */
549 while (idlen > 0 && con->id[idlen - 1] == '/')
551 p = ntarget = (char *)alloca (idlen + 1 + strlen (u->dir) + 1);
552 memcpy (p, con->id, idlen);
557 DEBUGP (("Prepended initial PWD to relative path:\n"));
558 DEBUGP ((" pwd: '%s'\n old: '%s'\n new: '%s'\n",
559 con->id, target, ntarget));
565 Don't help me out. Please.
566 A reasonably recent VMS FTP server will cope just fine with
567 UNIX file specifications. This code just spoils things.
568 Discarding the device name, for example, is not a wise
570 This code was disabled but left in as an example of what
574 /* If the FTP host runs VMS, we will have to convert the absolute
575 directory path in UNIX notation to absolute directory path in
576 VMS notation as VMS FTP servers do not like UNIX notation of
577 absolute paths. "VMS notation" is [dir.subdir.subsubdir]. */
579 if (con->rs == ST_VMS)
582 char *ntarget = (char *)alloca (strlen (target) + 2);
583 /* We use a converted initial dir, so directories in
584 TARGET will be separated with slashes, something like
585 "/INITIAL/FOLDER/DIR/SUBDIR". Convert that to
586 "[INITIAL.FOLDER.DIR.SUBDIR]". */
587 strcpy (ntarget, target);
588 assert (*ntarget == '/');
590 for (tmpp = ntarget + 1; *tmpp; tmpp++)
595 DEBUGP (("Changed file name to VMS syntax:\n"));
596 DEBUGP ((" Unix: '%s'\n VMS: '%s'\n", target, ntarget));
602 A relative directory is relative to the initial directory.
603 Thus, what _is_ useful on VMS (and probably elsewhere) is
604 to CWD to the initial directory (ideally, whatever the
605 server reports, _exactly_, NOT badly UNIX-ixed), and then
606 CWD to the (new) relative directory. This should probably
607 be restructured as a function, called once or twice, but
608 I'm lazy enough to take the badly indented loop short-cut
612 /* Decide on one pass (absolute) or two (relative).
613 The VMS restriction may be relaxed when the squirrely code
616 if ((con->rs == ST_VMS) && (target[0] != '/'))
619 DEBUGP (("Using two-step CWD for relative path.\n"));
623 /* Go straight to the target. */
627 /* At least one VMS FTP server (TCPware V5.6-2) can switch to
628 a UNIX emulation mode when given a UNIX-like directory
629 specification (like "a/b/c"). If allowed to continue this
630 way, LIST interpretation will be confused, because the
631 system type (SYST response) will not be re-checked, and
632 future UNIX-format directory listings (for multiple URLs or
633 "-r") will be horribly misinterpreted.
635 The cheap and nasty work-around is to do a "CWD []" after a
636 UNIX-like directory specification is used. (A single-level
637 directory is harmless.) This puts the TCPware server back
638 into VMS mode, and does no harm on other servers.
640 Unlike the rest of this block, this particular behavior
641 _is_ VMS-specific, so it gets its own VMS test.
643 if ((con->rs == ST_VMS) && (strchr( target, '/') != NULL))
646 DEBUGP (("Using extra \"CWD []\" step for VMS server.\n"));
653 /* 2004-09-20 SMS. */
654 /* Sorry about the deviant indenting. Laziness. */
656 for (cwd_count = cwd_start; cwd_count < cwd_end; cwd_count++)
661 /* Step one (optional): Go to the initial directory,
662 exactly as reported by the server.
668 /* Step two: Go to the target directory. (Absolute or
669 relative will work now.)
675 /* Step three (optional): "CWD []" to restore server
686 if (!opt.server_response)
687 logprintf (LOG_VERBOSE, "==> CWD (%d) %s ... ", cwd_count,
688 quotearg_style (escape_quoting_style, target));
689 err = ftp_cwd (csock, target);
690 /* FTPRERR, WRITEFAILED, FTPNSFOD */
694 logputs (LOG_VERBOSE, "\n");
695 logputs (LOG_NOTQUIET, _("\
696 Error in server response, closing control connection.\n"));
701 logputs (LOG_VERBOSE, "\n");
702 logputs (LOG_NOTQUIET,
703 _("Write failed, closing control connection.\n"));
708 logputs (LOG_VERBOSE, "\n");
709 logprintf (LOG_NOTQUIET, _("No such directory %s.\n\n"),
719 if (!opt.server_response)
720 logputs (LOG_VERBOSE, _("done.\n"));
724 /* 2004-09-20 SMS. */
725 /* End of deviant indenting. */
729 else /* do not CWD */
730 logputs (LOG_VERBOSE, _("==> CWD not required.\n"));
732 if ((cmd & DO_RETR) && *len == 0)
736 if (!opt.server_response)
737 logprintf (LOG_VERBOSE, "==> SIZE %s ... ",
738 quotearg_style (escape_quoting_style, u->file));
741 err = ftp_size (csock, u->file, len);
747 logputs (LOG_VERBOSE, "\n");
748 logputs (LOG_NOTQUIET, _("\
749 Error in server response, closing control connection.\n"));
754 /* Everything is OK. */
759 if (!opt.server_response)
760 logprintf (LOG_VERBOSE, *len ? "%s\n" : _("done.\n"),
761 number_to_static_string (*len));
764 /* If anything is to be retrieved, PORT (or PASV) must be sent. */
765 if (cmd & (DO_LIST | DO_RETR))
769 ip_address passive_addr;
771 err = ftp_do_pasv (csock, &passive_addr, &passive_port);
772 /* FTPRERR, WRITEFAILED, FTPNOPASV, FTPINVPASV */
776 logputs (LOG_VERBOSE, "\n");
777 logputs (LOG_NOTQUIET, _("\
778 Error in server response, closing control connection.\n"));
783 logputs (LOG_VERBOSE, "\n");
784 logputs (LOG_NOTQUIET,
785 _("Write failed, closing control connection.\n"));
790 logputs (LOG_VERBOSE, "\n");
791 logputs (LOG_NOTQUIET, _("Cannot initiate PASV transfer.\n"));
794 logputs (LOG_VERBOSE, "\n");
795 logputs (LOG_NOTQUIET, _("Cannot parse PASV response.\n"));
804 DEBUGP (("trying to connect to %s port %d\n",
805 print_address (&passive_addr), passive_port));
806 dtsock = connect_to_ip (&passive_addr, passive_port, NULL);
809 int save_errno = errno;
812 logprintf (LOG_VERBOSE, _("couldn't connect to %s port %d: %s\n"),
813 print_address (&passive_addr), passive_port,
814 strerror (save_errno));
815 return (retryable_socket_connect_error (save_errno)
816 ? CONERROR : CONIMPOSSIBLE);
819 pasv_mode_open = true; /* Flag to avoid accept port */
820 if (!opt.server_response)
821 logputs (LOG_VERBOSE, _("done. "));
825 if (!pasv_mode_open) /* Try to use a port command if PASV failed */
827 err = ftp_do_port (csock, &local_sock);
828 /* FTPRERR, WRITEFAILED, bindport (FTPSYSERR), HOSTERR,
833 logputs (LOG_VERBOSE, "\n");
834 logputs (LOG_NOTQUIET, _("\
835 Error in server response, closing control connection.\n"));
839 fd_close (local_sock);
842 logputs (LOG_VERBOSE, "\n");
843 logputs (LOG_NOTQUIET,
844 _("Write failed, closing control connection.\n"));
848 fd_close (local_sock);
851 logputs (LOG_VERBOSE, "\n");
852 logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
856 fd_close (local_sock);
859 logputs (LOG_VERBOSE, "\n");
860 logprintf (LOG_NOTQUIET, _("Bind error (%s).\n"),
865 logputs (LOG_VERBOSE, "\n");
866 logputs (LOG_NOTQUIET, _("Invalid PORT.\n"));
870 fd_close (local_sock);
877 if (!opt.server_response)
878 logputs (LOG_VERBOSE, _("done. "));
880 } /* cmd & (DO_LIST | DO_RETR) */
882 /* Restart if needed. */
883 if (restval && (cmd & DO_RETR))
885 if (!opt.server_response)
886 logprintf (LOG_VERBOSE, "==> REST %s ... ",
887 number_to_static_string (restval));
888 err = ftp_rest (csock, restval);
890 /* FTPRERR, WRITEFAILED, FTPRESTFAIL */
894 logputs (LOG_VERBOSE, "\n");
895 logputs (LOG_NOTQUIET, _("\
896 Error in server response, closing control connection.\n"));
900 fd_close (local_sock);
903 logputs (LOG_VERBOSE, "\n");
904 logputs (LOG_NOTQUIET,
905 _("Write failed, closing control connection.\n"));
909 fd_close (local_sock);
912 logputs (LOG_VERBOSE, _("\nREST failed, starting from scratch.\n"));
920 if (err != FTPRESTFAIL && !opt.server_response)
921 logputs (LOG_VERBOSE, _("done. "));
922 } /* restval && cmd & DO_RETR */
926 /* If we're in spider mode, don't really retrieve anything except
927 the directory listing and verify whether the given "file" exists. */
933 res = ftp_get_listing (u, con, &f);
934 /* Set the DO_RETR command flag again, because it gets unset when
935 calling ftp_get_listing() and would otherwise cause an assertion
936 failure earlier on when this function gets repeatedly called
937 (e.g., when recursing). */
943 if (!strcmp (f->name, u->file))
952 logputs (LOG_VERBOSE, "\n");
953 logprintf (LOG_NOTQUIET, _("File %s exists.\n"),
958 logputs (LOG_VERBOSE, "\n");
959 logprintf (LOG_NOTQUIET, _("No such file %s.\n"),
966 fd_close (local_sock);
972 if (!opt.server_response)
975 logputs (LOG_VERBOSE, "\n");
976 logprintf (LOG_VERBOSE, "==> RETR %s ... ",
977 quotearg_style (escape_quoting_style, u->file));
981 err = ftp_retr (csock, u->file);
982 /* FTPRERR, WRITEFAILED, FTPNSFOD */
986 logputs (LOG_VERBOSE, "\n");
987 logputs (LOG_NOTQUIET, _("\
988 Error in server response, closing control connection.\n"));
992 fd_close (local_sock);
995 logputs (LOG_VERBOSE, "\n");
996 logputs (LOG_NOTQUIET,
997 _("Write failed, closing control connection.\n"));
1001 fd_close (local_sock);
1004 logputs (LOG_VERBOSE, "\n");
1005 logprintf (LOG_NOTQUIET, _("No such file %s.\n\n"),
1008 fd_close (local_sock);
1016 if (!opt.server_response)
1017 logputs (LOG_VERBOSE, _("done.\n"));
1018 expected_bytes = ftp_expected_bytes (ftp_last_respline);
1023 if (!opt.server_response)
1024 logputs (LOG_VERBOSE, "==> LIST ... ");
1025 /* As Maciej W. Rozycki (macro@ds2.pg.gda.pl) says, `LIST'
1026 without arguments is better than `LIST .'; confirmed by
1028 err = ftp_list (csock, NULL, con->rs);
1029 /* FTPRERR, WRITEFAILED */
1033 logputs (LOG_VERBOSE, "\n");
1034 logputs (LOG_NOTQUIET, _("\
1035 Error in server response, closing control connection.\n"));
1039 fd_close (local_sock);
1042 logputs (LOG_VERBOSE, "\n");
1043 logputs (LOG_NOTQUIET,
1044 _("Write failed, closing control connection.\n"));
1048 fd_close (local_sock);
1051 logputs (LOG_VERBOSE, "\n");
1052 logprintf (LOG_NOTQUIET, _("No such file or directory %s.\n\n"),
1055 fd_close (local_sock);
1062 if (!opt.server_response)
1063 logputs (LOG_VERBOSE, _("done.\n"));
1064 expected_bytes = ftp_expected_bytes (ftp_last_respline);
1065 } /* cmd & DO_LIST */
1067 if (!(cmd & (DO_LIST | DO_RETR)) || (opt.spider && !(cmd & DO_LIST)))
1068 return RETRFINISHED;
1070 /* Some FTP servers return the total length of file after REST
1071 command, others just return the remaining size. */
1072 if (*len && restval && expected_bytes
1073 && (expected_bytes == *len - restval))
1075 DEBUGP (("Lying FTP server found, adjusting.\n"));
1076 expected_bytes = *len;
1079 /* If no transmission was required, then everything is OK. */
1080 if (!pasv_mode_open) /* we are not using pasive mode so we need
1083 /* Wait for the server to connect to the address we're waiting
1085 dtsock = accept_connection (local_sock);
1088 logprintf (LOG_NOTQUIET, "accept: %s\n", strerror (errno));
1093 /* Open the file -- if output_stream is set, use it instead. */
1096 Note that having the output_stream ("-O") file opened in main()
1097 (main.c) rather limits the ability in VMS to open the file
1098 differently for ASCII versus binary FTP here. (Of course, doing it
1099 there allows a open failure to be detected immediately, without first
1100 connecting to the server.)
1102 if (!output_stream || con->cmd & DO_LIST)
1104 /* On VMS, alter the name as required. */
1108 targ = ods_conform (con->target);
1109 if (targ != con->target)
1111 xfree (con->target);
1114 #endif /* def __VMS */
1116 mkalldirs (con->target);
1118 rotate_backups (con->target);
1121 For VMS, define common fopen() optional arguments, and a handy macro
1122 for use as a variable "binary" flag.
1123 Elsewhere, define a constant "binary" flag.
1124 Isn't it nice to have distinct text and binary file types?
1126 # define BIN_TYPE_TRANSFER (type_char != 'A')
1128 # define FOPEN_OPT_ARGS "fop=sqo", "acc", acc_cb, &open_id
1129 # define FOPEN_OPT_ARGS_BIN "ctx=bin,stm", "rfm=fix", "mrs=512" FOPEN_OPT_ARGS
1130 # define BIN_TYPE_FILE (BIN_TYPE_TRANSFER && (opt.ftp_stmlf == 0))
1131 #else /* def __VMS */
1132 # define BIN_TYPE_FILE 1
1133 #endif /* def __VMS [else] */
1135 if (restval && !(con->cmd & DO_LIST))
1143 fp = fopen (con->target, "ab", FOPEN_OPT_ARGS_BIN);
1148 fp = fopen (con->target, "a", FOPEN_OPT_ARGS);
1150 #else /* def __VMS */
1151 fp = fopen (con->target, "ab");
1152 #endif /* def __VMS [else] */
1154 else if (opt.noclobber || opt.always_rest || opt.timestamping || opt.dirstruct
1155 || opt.output_document)
1163 fp = fopen (con->target, "wb", FOPEN_OPT_ARGS_BIN);
1168 fp = fopen (con->target, "w", FOPEN_OPT_ARGS);
1170 #else /* def __VMS */
1171 fp = fopen (con->target, "wb");
1172 #endif /* def __VMS [else] */
1176 fp = fopen_excl (con->target, true);
1177 if (!fp && errno == EEXIST)
1179 /* We cannot just invent a new name and use it (which is
1180 what functions like unique_create typically do)
1181 because we told the user we'd use this name.
1182 Instead, return and retry the download. */
1183 logprintf (LOG_NOTQUIET, _("%s has sprung into existence.\n"),
1188 fd_close (local_sock);
1189 return FOPEN_EXCL_ERR;
1194 logprintf (LOG_NOTQUIET, "%s: %s\n", con->target, strerror (errno));
1198 fd_close (local_sock);
1207 print_length (*len, restval, true);
1208 expected_bytes = *len; /* for fd_read_body's progress bar */
1210 else if (expected_bytes)
1211 print_length (expected_bytes, restval, false);
1213 /* Get the contents of the document. */
1215 if (restval && rest_failed)
1216 flags |= rb_skip_startpos;
1219 res = fd_read_body (dtsock, fp,
1220 expected_bytes ? expected_bytes - restval : 0,
1221 restval, &rd_size, len, &con->dltime, flags);
1223 tms = datetime_str (time (NULL));
1224 tmrate = retr_rate (rd_size, con->dltime);
1225 total_download_time += con->dltime;
1227 fd_close (local_sock);
1228 /* Close the local file. */
1229 if (!output_stream || con->cmd & DO_LIST)
1232 /* If fd_read_body couldn't write to fp, bail out. */
1235 logprintf (LOG_NOTQUIET, _("%s: %s, closing control connection.\n"),
1236 con->target, strerror (errno));
1244 logprintf (LOG_NOTQUIET, _("%s (%s) - Data connection: %s; "),
1245 tms, tmrate, fd_errstr (dtsock));
1246 if (opt.server_response)
1247 logputs (LOG_ALWAYS, "\n");
1251 /* Get the server to tell us if everything is retrieved. */
1252 err = ftp_response (csock, &respline);
1255 /* The control connection is decidedly closed. Print the time
1256 only if it hasn't already been printed. */
1258 logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
1259 logputs (LOG_NOTQUIET, _("Control connection closed.\n"));
1260 /* If there is an error on the control connection, close it, but
1261 return FTPRETRINT, since there is a possibility that the
1262 whole file was retrieved nevertheless (but that is for
1263 ftp_loop_internal to decide). */
1267 } /* err != FTPOK */
1268 /* If retrieval failed for any reason, return FTPRETRINT, but do not
1269 close socket, since the control connection is still alive. If
1270 there is something wrong with the control connection, it will
1271 become apparent later. */
1272 if (*respline != '2')
1276 logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
1277 logputs (LOG_NOTQUIET, _("Data transfer aborted.\n"));
1284 /* What now? The data connection was erroneous, whereas the
1285 response says everything is OK. We shall play it safe. */
1289 if (!(cmd & LEAVE_PENDING))
1291 /* Closing the socket is faster than sending 'QUIT' and the
1292 effect is the same. */
1296 /* If it was a listing, and opt.server_response is true,
1298 if (opt.server_response && (con->cmd & DO_LIST))
1301 Much of this work may already have been done, but repeating it should
1302 do no damage beyond wasting time.
1304 /* On VMS, alter the name as required. */
1308 targ = ods_conform( con->target);
1309 if (targ != con->target)
1311 xfree( con->target);
1314 #endif /* def __VMS */
1316 mkalldirs (con->target);
1317 fp = fopen (con->target, "r");
1319 logprintf (LOG_ALWAYS, "%s: %s\n", con->target, strerror (errno));
1323 /* The lines are being read with read_whole_line because of
1324 no-buffering on opt.lfile. */
1325 while ((line = read_whole_line (fp)) != NULL)
1327 char *p = strchr (line, '\0');
1328 while (p > line && (p[-1] == '\n' || p[-1] == '\r'))
1330 logprintf (LOG_ALWAYS, "%s\n",
1331 quotearg_style (escape_quoting_style, line));
1336 } /* con->cmd & DO_LIST && server_response */
1338 return RETRFINISHED;
1341 /* A one-file FTP loop. This is the part where FTP retrieval is
1342 retried, and retried, and retried, and...
1344 This loop either gets commands from con, or (if ON_YOUR_OWN is
1345 set), makes them up to retrieve the file given by the URL. */
1347 ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
1350 wgint restval, len = 0;
1352 const char *tmrate = NULL;
1356 /* Get the target, and set the name for the message accordingly. */
1357 if ((f == NULL) && (con->target))
1359 /* Explicit file (like ".listing"). */
1364 /* URL-derived file. Consider "-O file" name. */
1365 con->target = url_file_name (u);
1366 if (!opt.output_document)
1369 locf = opt.output_document;
1372 /* If the output_document was given, then this check was already done and
1373 the file didn't exist. Hence the !opt.output_document */
1374 if (opt.noclobber && !opt.output_document && file_exists_p (con->target))
1376 logprintf (LOG_VERBOSE,
1377 _("File %s already there; not retrieving.\n"), quote (con->target));
1378 /* If the file is there, we suppose it's retrieved OK. */
1382 /* Remove it if it's a link. */
1383 remove_link (con->target);
1387 if (con->st & ON_YOUR_OWN)
1388 con->st = ON_YOUR_OWN;
1390 orig_lp = con->cmd & LEAVE_PENDING ? 1 : 0;
1395 /* Increment the pass counter. */
1397 sleep_between_retrievals (count);
1398 if (con->st & ON_YOUR_OWN)
1401 con->cmd |= (DO_RETR | LEAVE_PENDING);
1402 if (con->csock != -1)
1403 con->cmd &= ~ (DO_LOGIN | DO_CWD);
1405 con->cmd |= (DO_LOGIN | DO_CWD);
1407 else /* not on your own */
1409 if (con->csock != -1)
1410 con->cmd &= ~DO_LOGIN;
1412 con->cmd |= DO_LOGIN;
1413 if (con->st & DONE_CWD)
1414 con->cmd &= ~DO_CWD;
1419 /* Decide whether or not to restart. */
1420 if (con->cmd & DO_LIST)
1422 else if (opt.always_rest
1423 && stat (locf, &st) == 0
1424 && S_ISREG (st.st_mode))
1425 /* When -c is used, continue from on-disk size. (Can't use
1426 hstat.len even if count>1 because we don't want a failed
1427 first attempt to clobber existing data.) */
1428 restval = st.st_size;
1430 restval = len; /* start where the previous run left off */
1434 /* Get the current time string. */
1435 tms = datetime_str (time (NULL));
1436 /* Print fetch message, if opt.verbose. */
1439 char *hurl = url_string (u, URL_AUTH_HIDE_PASSWD);
1443 sprintf (tmp, _("(try:%2d)"), count);
1444 logprintf (LOG_VERBOSE, "--%s-- %s\n %s => %s\n",
1445 tms, hurl, tmp, quote (locf));
1447 ws_changetitle (hurl);
1451 /* Send getftp the proper length, if fileinfo was provided. */
1456 err = getftp (u, &len, restval, con);
1458 if (con->csock == -1)
1459 con->st &= ~DONE_CWD;
1461 con->st |= DONE_CWD;
1465 case HOSTERR: case CONIMPOSSIBLE: case FWRITEERR: case FOPENERR:
1466 case FTPNSFOD: case FTPLOGINC: case FTPNOPASV: case CONTNOTSUPPORTED:
1467 /* Fatal errors, give up. */
1469 case CONSOCKERR: case CONERROR: case FTPSRVERR: case FTPRERR:
1470 case WRITEFAILED: case FTPUNKNOWNTYPE: case FTPSYSERR:
1471 case FTPPORTERR: case FTPLOGREFUSED: case FTPINVPASV:
1472 case FOPEN_EXCL_ERR:
1473 printwhat (count, opt.ntry);
1474 /* non-fatal errors */
1475 if (err == FOPEN_EXCL_ERR)
1477 /* Re-determine the file name. */
1478 xfree_null (con->target);
1479 con->target = url_file_name (u);
1484 /* If the control connection was closed, the retrieval
1485 will be considered OK if f->size == len. */
1486 if (!f || len != f->size)
1488 printwhat (count, opt.ntry);
1499 tms = datetime_str (time (NULL));
1501 tmrate = retr_rate (len - restval, con->dltime);
1503 /* If we get out of the switch above without continue'ing, we've
1504 successfully downloaded a file. Remember this fact. */
1505 downloaded_file (FILE_DOWNLOADED_NORMALLY, locf);
1507 if (con->st & ON_YOUR_OWN)
1509 fd_close (con->csock);
1514 bool write_to_stdout = (opt.output_document && HYPHENP (opt.output_document));
1516 logprintf (LOG_VERBOSE,
1518 ? _("%s (%s) - written to stdout %s[%s]\n\n")
1519 : _("%s (%s) - %s saved [%s]\n\n"),
1521 write_to_stdout ? "" : quote (locf),
1522 number_to_static_string (len));
1524 if (!opt.verbose && !opt.quiet)
1526 /* Need to hide the password from the URL. The `if' is here
1527 so that we don't do the needless allocation every
1529 char *hurl = url_string (u, URL_AUTH_HIDE_PASSWD);
1530 logprintf (LOG_NONVERBOSE, "%s URL: %s [%s] -> \"%s\" [%d]\n",
1531 tms, hurl, number_to_static_string (len), locf, count);
1535 if ((con->cmd & DO_LIST))
1536 /* This is a directory listing file. */
1538 if (!opt.remove_listing)
1539 /* --dont-remove-listing was specified, so do count this towards the
1540 number of bytes and files downloaded. */
1542 total_downloaded_bytes += len;
1546 /* Deletion of listing files is not controlled by --delete-after, but
1547 by the more specific option --dont-remove-listing, and the code
1548 to do this deletion is in another function. */
1550 else if (!opt.spider)
1551 /* This is not a directory listing file. */
1553 /* Unlike directory listing files, don't pretend normal files weren't
1554 downloaded if they're going to be deleted. People seeding proxies,
1555 for instance, may want to know how many bytes and files they've
1556 downloaded through it. */
1557 total_downloaded_bytes += len;
1560 if (opt.delete_after)
1563 Removing file due to --delete-after in ftp_loop_internal():\n"));
1564 logprintf (LOG_VERBOSE, _("Removing %s.\n"), locf);
1566 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1570 /* Restore the original leave-pendingness. */
1572 con->cmd |= LEAVE_PENDING;
1574 con->cmd &= ~LEAVE_PENDING;
1576 } while (!opt.ntry || (count < opt.ntry));
1578 if (con->csock != -1 && (con->st & ON_YOUR_OWN))
1580 fd_close (con->csock);
1586 /* Return the directory listing in a reusable format. The directory
1587 is specifed in u->dir. */
1589 ftp_get_listing (struct url *u, ccon *con, struct fileinfo **f)
1592 char *uf; /* url file name */
1593 char *lf; /* list file name */
1594 char *old_target = con->target;
1596 con->st &= ~ON_YOUR_OWN;
1597 con->cmd |= (DO_LIST | LEAVE_PENDING);
1598 con->cmd &= ~DO_RETR;
1600 /* Find the listing file name. We do it by taking the file name of
1601 the URL and replacing the last component with the listing file
1603 uf = url_file_name (u);
1604 lf = file_merge (uf, LIST_FILENAME);
1606 DEBUGP ((_("Using %s as listing tmp file.\n"), quote (lf)));
1608 con->target = xstrdup (lf);
1610 err = ftp_loop_internal (u, NULL, con);
1611 lf = xstrdup (con->target);
1612 xfree (con->target);
1613 con->target = old_target;
1617 *f = ftp_parse_ls (lf, con->rs);
1618 if (opt.remove_listing)
1621 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1623 logprintf (LOG_VERBOSE, _("Removed %s.\n"), quote (lf));
1629 con->cmd &= ~DO_LIST;
1633 static uerr_t ftp_retrieve_dirs (struct url *, struct fileinfo *, ccon *);
1634 static uerr_t ftp_retrieve_glob (struct url *, ccon *, int);
1635 static struct fileinfo *delelement (struct fileinfo *, struct fileinfo **);
1636 static void freefileinfo (struct fileinfo *f);
1638 /* Retrieve a list of files given in struct fileinfo linked list. If
1639 a file is a symbolic link, do not retrieve it, but rather try to
1640 set up a similar link on the local disk, if the symlinks are
1643 If opt.recursive is set, after all files have been retrieved,
1644 ftp_retrieve_dirs will be called to retrieve the directories. */
1646 ftp_retrieve_list (struct url *u, struct fileinfo *f, ccon *con)
1648 static int depth = 0;
1650 struct fileinfo *orig;
1653 bool dlthis; /* Download this (file). */
1654 const char *actual_target = NULL;
1656 /* Increase the depth. */
1658 if (opt.reclevel != INFINITE_RECURSION && depth > opt.reclevel)
1660 DEBUGP ((_("Recursion depth %d exceeded max. depth %d.\n"),
1661 depth, opt.reclevel));
1669 con->st &= ~ON_YOUR_OWN;
1670 if (!(con->st & DONE_CWD))
1673 con->cmd &= ~DO_CWD;
1674 con->cmd |= (DO_RETR | LEAVE_PENDING);
1677 con->cmd |= DO_LOGIN;
1679 con->cmd &= ~DO_LOGIN;
1681 err = RETROK; /* in case it's not used */
1685 char *old_target, *ofile;
1687 if (opt.quota && total_downloaded_bytes > opt.quota)
1692 old_target = con->target;
1694 ofile = xstrdup (u->file);
1695 url_set_file (u, f->name);
1697 con->target = url_file_name (u);
1701 if (opt.timestamping && f->type == FT_PLAINFILE)
1704 /* If conversion of HTML files retrieved via FTP is ever implemented,
1705 we'll need to stat() <file>.orig here when -K has been specified.
1706 I'm not implementing it now since files on an FTP server are much
1707 more likely than files on an HTTP server to legitimately have a
1709 if (!stat (con->target, &st))
1713 /* Else, get it from the file. */
1714 local_size = st.st_size;
1717 /* Modification time granularity is 2 seconds for Windows, so
1718 increase local time by 1 second for later comparison. */
1721 /* Compare file sizes only for servers that tell us correct
1722 values. Assume sizes being equal for servers that lie
1724 cor_val = (con->rs == ST_UNIX || con->rs == ST_WINNT);
1725 eq_size = cor_val ? (local_size == f->size) : true;
1726 if (f->tstamp <= tml && eq_size)
1728 /* Remote file is older, file sizes can be compared and
1730 logprintf (LOG_VERBOSE, _("\
1731 Remote file no newer than local file %s -- not retrieving.\n"), quote (con->target));
1736 /* Remote file is newer or sizes cannot be matched */
1737 logprintf (LOG_VERBOSE, _("\
1738 Remote file is newer than local file %s -- retrieving.\n\n"),
1739 quote (con->target));
1743 /* Sizes do not match */
1744 logprintf (LOG_VERBOSE, _("\
1745 The sizes do not match (local %s) -- retrieving.\n\n"),
1746 number_to_static_string (local_size));
1749 } /* opt.timestamping && f->type == FT_PLAINFILE */
1753 /* If opt.retr_symlinks is defined, we treat symlinks as
1754 if they were normal files. There is currently no way
1755 to distinguish whether they might be directories, and
1757 if (!opt.retr_symlinks)
1761 logputs (LOG_NOTQUIET,
1762 _("Invalid name of the symlink, skipping.\n"));
1766 /* Check whether we already have the correct
1768 int rc = lstat (con->target, &st);
1771 size_t len = strlen (f->linkto) + 1;
1772 if (S_ISLNK (st.st_mode))
1774 char *link_target = (char *)alloca (len);
1775 size_t n = readlink (con->target, link_target, len);
1777 && (memcmp (link_target, f->linkto, n) == 0))
1779 logprintf (LOG_VERBOSE, _("\
1780 Already have correct symlink %s -> %s\n\n"),
1781 quote (con->target),
1788 logprintf (LOG_VERBOSE, _("Creating symlink %s -> %s\n"),
1789 quote (con->target), quote (f->linkto));
1790 /* Unlink before creating symlink! */
1791 unlink (con->target);
1792 if (symlink (f->linkto, con->target) == -1)
1793 logprintf (LOG_NOTQUIET, "symlink: %s\n", strerror (errno));
1794 logputs (LOG_VERBOSE, "\n");
1795 } /* have f->linkto */
1796 #else /* not HAVE_SYMLINK */
1797 logprintf (LOG_NOTQUIET,
1798 _("Symlinks not supported, skipping symlink %s.\n"),
1799 quote (con->target));
1800 #endif /* not HAVE_SYMLINK */
1802 else /* opt.retr_symlinks */
1805 err = ftp_loop_internal (u, f, con);
1806 } /* opt.retr_symlinks */
1810 logprintf (LOG_NOTQUIET, _("Skipping directory %s.\n"),
1814 /* Call the retrieve loop. */
1816 err = ftp_loop_internal (u, f, con);
1819 logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
1826 * Set permissions _before_ setting the times, as setting the
1827 * permissions changes the modified-time, at least on VMS.
1828 * Also, use the opt.output_document name here, too, as
1829 * appropriate. (Do the test once, and save the result.)
1832 set_local_file (&actual_target, con->target);
1834 /* If downloading a plain file, set valid (non-zero) permissions. */
1835 if (dlthis && (actual_target != NULL) && (f->type == FT_PLAINFILE))
1838 chmod (actual_target, f->perms);
1840 DEBUGP (("Unrecognized permissions for %s.\n", actual_target));
1843 /* Set the time-stamp information to the local file. Symlinks
1844 are not to be stamped because it sets the stamp on the
1846 if (actual_target != NULL)
1848 if (!(f->type == FT_SYMLINK && !opt.retr_symlinks)
1851 && file_exists_p (con->target))
1853 touch (actual_target, f->tstamp);
1855 else if (f->tstamp == -1)
1856 logprintf (LOG_NOTQUIET, _("%s: corrupt time-stamp.\n"),
1860 xfree (con->target);
1861 con->target = old_target;
1863 url_set_file (u, ofile);
1866 /* Break on fatals. */
1867 if (err == QUOTEXC || err == HOSTERR || err == FWRITEERR)
1869 con->cmd &= ~ (DO_CWD | DO_LOGIN);
1873 /* We do not want to call ftp_retrieve_dirs here */
1874 if (opt.recursive &&
1875 !(opt.reclevel != INFINITE_RECURSION && depth >= opt.reclevel))
1876 err = ftp_retrieve_dirs (u, orig, con);
1877 else if (opt.recursive)
1878 DEBUGP ((_("Will not retrieve dirs since depth is %d (max %d).\n"),
1879 depth, opt.reclevel));
1884 /* Retrieve the directories given in a file list. This function works
1885 by simply going through the linked list and calling
1886 ftp_retrieve_glob on each directory entry. The function knows
1887 about excluded directories. */
1889 ftp_retrieve_dirs (struct url *u, struct fileinfo *f, ccon *con)
1891 char *container = NULL;
1892 int container_size = 0;
1894 for (; f; f = f->next)
1897 char *odir, *newdir;
1899 if (opt.quota && total_downloaded_bytes > opt.quota)
1901 if (f->type != FT_DIRECTORY)
1904 /* Allocate u->dir off stack, but reallocate only if a larger
1905 string is needed. It's a pity there's no "realloca" for an
1906 item on the bottom of the stack. */
1907 size = strlen (u->dir) + 1 + strlen (f->name) + 1;
1908 if (size > container_size)
1909 container = (char *)alloca (size);
1914 || (*odir == '/' && *(odir + 1) == '\0'))
1915 /* If ODIR is empty or just "/", simply append f->name to
1916 ODIR. (In the former case, to preserve u->dir being
1917 relative; in the latter case, to avoid double slash.) */
1918 sprintf (newdir, "%s%s", odir, f->name);
1920 /* Else, use a separator. */
1921 sprintf (newdir, "%s/%s", odir, f->name);
1923 DEBUGP (("Composing new CWD relative to the initial directory.\n"));
1924 DEBUGP ((" odir = '%s'\n f->name = '%s'\n newdir = '%s'\n\n",
1925 odir, f->name, newdir));
1926 if (!accdir (newdir))
1928 logprintf (LOG_VERBOSE, _("\
1929 Not descending to %s as it is excluded/not-included.\n"),
1934 con->st &= ~DONE_CWD;
1936 odir = xstrdup (u->dir); /* because url_set_dir will free
1938 url_set_dir (u, newdir);
1939 ftp_retrieve_glob (u, con, GLOB_GETALL);
1940 url_set_dir (u, odir);
1943 /* Set the time-stamp? */
1946 if (opt.quota && total_downloaded_bytes > opt.quota)
1952 /* Return true if S has a leading '/' or contains '../' */
1954 has_insecure_name_p (const char *s)
1959 if (strstr (s, "../") != 0)
1965 /* A near-top-level function to retrieve the files in a directory.
1966 The function calls ftp_get_listing, to get a linked list of files.
1967 Then it weeds out the file names that do not match the pattern.
1968 ftp_retrieve_list is called with this updated list as an argument.
1970 If the argument ACTION is GLOB_GETONE, just download the file (but
1971 first get the listing, so that the time-stamp is heeded); if it's
1972 GLOB_GLOBALL, use globbing; if it's GLOB_GETALL, download the whole
1975 ftp_retrieve_glob (struct url *u, ccon *con, int action)
1977 struct fileinfo *f, *start;
1980 con->cmd |= LEAVE_PENDING;
1982 res = ftp_get_listing (u, con, &start);
1985 /* First: weed out that do not conform the global rules given in
1986 opt.accepts and opt.rejects. */
1987 if (opt.accepts || opt.rejects)
1992 if (f->type != FT_DIRECTORY && !acceptable (f->name))
1994 logprintf (LOG_VERBOSE, _("Rejecting %s.\n"),
1996 f = delelement (f, &start);
2002 /* Remove all files with possible harmful names */
2006 if (has_insecure_name_p (f->name))
2008 logprintf (LOG_VERBOSE, _("Rejecting %s.\n"),
2010 f = delelement (f, &start);
2015 /* Now weed out the files that do not match our globbing pattern.
2016 If we are dealing with a globbing pattern, that is. */
2019 if (action == GLOB_GLOBALL)
2021 int (*matcher) (const char *, const char *, int)
2022 = opt.ignore_case ? fnmatch_nocase : fnmatch;
2028 matchres = matcher (u->file, f->name, 0);
2031 logprintf (LOG_NOTQUIET, _("Error matching %s against %s: %s\n"),
2032 u->file, quotearg_style (escape_quoting_style, f->name),
2036 if (matchres == FNM_NOMATCH)
2037 f = delelement (f, &start); /* delete the element from the list */
2039 f = f->next; /* leave the element in the list */
2043 freefileinfo (start);
2044 return RETRBADPATTERN;
2047 else if (action == GLOB_GETONE)
2049 int (*cmp) (const char *, const char *)
2050 = opt.ignore_case ? strcasecmp : strcmp;
2054 if (0 != cmp(u->file, f->name))
2055 f = delelement (f, &start);
2063 /* Just get everything. */
2064 ftp_retrieve_list (u, start, con);
2068 if (action == GLOB_GLOBALL)
2071 /* #### This message SUCKS. We should see what was the
2072 reason that nothing was retrieved. */
2073 logprintf (LOG_VERBOSE, _("No matches on pattern %s.\n"),
2076 else if (action == GLOB_GETONE) /* GLOB_GETONE or GLOB_GETALL */
2078 /* Let's try retrieving it anyway. */
2079 con->st |= ON_YOUR_OWN;
2080 res = ftp_loop_internal (u, NULL, con);
2084 /* If action == GLOB_GETALL, and the file list is empty, there's
2085 no point in trying to download anything or in complaining about
2086 it. (An empty directory should not cause complaints.)
2089 freefileinfo (start);
2090 if (opt.quota && total_downloaded_bytes > opt.quota)
2093 /* #### Should we return `res' here? */
2097 /* The wrapper that calls an appropriate routine according to contents
2098 of URL. Inherently, its capabilities are limited on what can be
2099 encoded into a URL. */
2101 ftp_loop (struct url *u, int *dt, struct url *proxy, bool recursive, bool glob)
2103 ccon con; /* FTP connection */
2111 con.st = ON_YOUR_OWN;
2116 /* If the file name is empty, the user probably wants a directory
2117 index. We'll provide one, properly HTML-ized. Unless
2118 opt.htmlify is 0, of course. :-) */
2119 if (!*u->file && !recursive)
2122 res = ftp_get_listing (u, &con, &f);
2126 if (opt.htmlify && !opt.spider)
2128 char *filename = (opt.output_document
2129 ? xstrdup (opt.output_document)
2130 : (con.target ? xstrdup (con.target)
2131 : url_file_name (u)));
2132 res = ftp_index (filename, u, f);
2133 if (res == FTPOK && opt.verbose)
2135 if (!opt.output_document)
2139 if (stat (filename, &st) == 0)
2143 logprintf (LOG_NOTQUIET,
2144 _("Wrote HTML-ized index to %s [%s].\n"),
2145 quote (filename), number_to_static_string (sz));
2148 logprintf (LOG_NOTQUIET,
2149 _("Wrote HTML-ized index to %s.\n"),
2159 bool ispattern = false;
2162 /* Treat the URL as a pattern if the file name part of the
2163 URL path contains wildcards. (Don't check for u->file
2164 because it is unescaped and therefore doesn't leave users
2165 the option to escape literal '*' as %2A.) */
2166 char *file_part = strrchr (u->path, '/');
2168 file_part = u->path;
2169 ispattern = has_wildcards_p (file_part);
2171 if (ispattern || recursive || opt.timestamping)
2173 /* ftp_retrieve_glob is a catch-all function that gets called
2174 if we need globbing, time-stamping or recursion. Its
2175 third argument is just what we really need. */
2176 res = ftp_retrieve_glob (u, &con,
2177 ispattern ? GLOB_GLOBALL : GLOB_GETONE);
2180 res = ftp_loop_internal (u, NULL, &con);
2186 /* If a connection was left, quench it. */
2187 if (con.csock != -1)
2188 fd_close (con.csock);
2189 xfree_null (con.id);
2191 xfree_null (con.target);
2196 /* Delete an element from the fileinfo linked list. Returns the
2197 address of the next element, or NULL if the list is exhausted. It
2198 can modify the start of the list. */
2199 static struct fileinfo *
2200 delelement (struct fileinfo *f, struct fileinfo **start)
2202 struct fileinfo *prev = f->prev;
2203 struct fileinfo *next = f->next;
2206 xfree_null (f->linkto);
2218 /* Free the fileinfo linked list of files. */
2220 freefileinfo (struct fileinfo *f)
2224 struct fileinfo *next = f->next;