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. */
51 #include "convert.h" /* for downloaded_file */
52 #include "recur.h" /* for INFINITE_RECURSION */
56 #endif /* def __VMS */
59 /* File where the "ls -al" listing will be saved. */
61 #define LIST_FILENAME "_listing"
63 #define LIST_FILENAME ".listing"
68 int st; /* connection status */
69 int cmd; /* command code */
70 int csock; /* control connection socket */
71 double dltime; /* time of the download in msecs */
72 enum stype rs; /* remote system reported by ftp server */
73 char *id; /* initial directory */
74 char *target; /* target file name */
75 struct url *proxy; /* FTWK-style proxy */
80 /* Look for regexp "( *[0-9]+ *byte" (literal parenthesis) anywhere in
81 the string S, and return the number converted to wgint, if found, 0
84 ftp_expected_bytes (const char *s)
90 while (*s && *s != '(')
94 ++s; /* skip the '(' */
95 res = str_to_wgint (s, (char **) &s, 10);
98 while (*s && c_isspace (*s))
102 if (c_tolower (*s) != 'b')
104 if (strncasecmp (s, "byte", 4))
114 * This function sets up a passive data connection with the FTP server.
115 * It is merely a wrapper around ftp_epsv, ftp_lpsv and ftp_pasv.
118 ftp_do_pasv (int csock, ip_address *addr, int *port)
122 /* We need to determine the address family and need to call
123 getpeername, so while we're at it, store the address to ADDR.
124 ftp_pasv and ftp_lpsv can simply override it. */
125 if (!socket_ip_address (csock, addr, ENDPOINT_PEER))
128 /* If our control connection is over IPv6, then we first try EPSV and then
129 * LPSV if the former is not supported. If the control connection is over
130 * IPv4, we simply issue the good old PASV request. */
131 switch (addr->family)
134 if (!opt.server_response)
135 logputs (LOG_VERBOSE, "==> PASV ... ");
136 err = ftp_pasv (csock, addr, port);
139 if (!opt.server_response)
140 logputs (LOG_VERBOSE, "==> EPSV ... ");
141 err = ftp_epsv (csock, addr, port);
143 /* If EPSV is not supported try LPSV */
144 if (err == FTPNOPASV)
146 if (!opt.server_response)
147 logputs (LOG_VERBOSE, "==> LPSV ... ");
148 err = ftp_lpsv (csock, addr, port);
159 * This function sets up an active data connection with the FTP server.
160 * It is merely a wrapper around ftp_eprt, ftp_lprt and ftp_port.
163 ftp_do_port (int csock, int *local_sock)
168 if (!socket_ip_address (csock, &cip, ENDPOINT_PEER))
171 /* If our control connection is over IPv6, then we first try EPRT and then
172 * LPRT if the former is not supported. If the control connection is over
173 * IPv4, we simply issue the good old PORT request. */
177 if (!opt.server_response)
178 logputs (LOG_VERBOSE, "==> PORT ... ");
179 err = ftp_port (csock, local_sock);
182 if (!opt.server_response)
183 logputs (LOG_VERBOSE, "==> EPRT ... ");
184 err = ftp_eprt (csock, local_sock);
186 /* If EPRT is not supported try LPRT */
187 if (err == FTPPORTERR)
189 if (!opt.server_response)
190 logputs (LOG_VERBOSE, "==> LPRT ... ");
191 err = ftp_lprt (csock, local_sock);
202 ftp_do_pasv (int csock, ip_address *addr, int *port)
204 if (!opt.server_response)
205 logputs (LOG_VERBOSE, "==> PASV ... ");
206 return ftp_pasv (csock, addr, port);
210 ftp_do_port (int csock, int *local_sock)
212 if (!opt.server_response)
213 logputs (LOG_VERBOSE, "==> PORT ... ");
214 return ftp_port (csock, local_sock);
219 print_length (wgint size, wgint start, bool authoritative)
221 logprintf (LOG_VERBOSE, _("Length: %s"), number_to_static_string (size));
223 logprintf (LOG_VERBOSE, " (%s)", human_readable (size));
226 if (size - start >= 1024)
227 logprintf (LOG_VERBOSE, _(", %s (%s) remaining"),
228 number_to_static_string (size - start),
229 human_readable (size - start));
231 logprintf (LOG_VERBOSE, _(", %s remaining"),
232 number_to_static_string (size - start));
234 logputs (LOG_VERBOSE, !authoritative ? _(" (unauthoritative)\n") : "\n");
237 static uerr_t ftp_get_listing (struct url *, ccon *, struct fileinfo **);
239 /* Retrieves a file with denoted parameters through opening an FTP
240 connection to the server. It always closes the data connection,
241 and closes the control connection in case of error. */
243 getftp (struct url *u, wgint *len, wgint restval, ccon *con)
245 int csock, dtsock, local_sock, res;
246 uerr_t err = RETROK; /* appease the compiler */
248 char *user, *passwd, *respline;
252 bool pasv_mode_open = false;
253 wgint expected_bytes = 0;
254 bool rest_failed = false;
259 assert (con != NULL);
260 assert (con->target != NULL);
262 /* Debug-check of the sanity of the request by making sure that LIST
263 and RETR are never both requested (since we can handle only one
265 assert (!((cmd & DO_LIST) && (cmd & DO_RETR)));
266 /* Make sure that at least *something* is requested. */
267 assert ((cmd & (DO_LIST | DO_CWD | DO_RETR | DO_LOGIN)) != 0);
271 search_netrc (u->host, (const char **)&user, (const char **)&passwd, 1);
272 user = user ? user : (opt.ftp_user ? opt.ftp_user : opt.user);
273 if (!user) user = "anonymous";
274 passwd = passwd ? passwd : (opt.ftp_passwd ? opt.ftp_passwd : opt.passwd);
275 if (!passwd) passwd = "-wget@";
281 if (!(cmd & DO_LOGIN))
283 else /* cmd & DO_LOGIN */
285 char *host = con->proxy ? con->proxy->host : u->host;
286 int port = con->proxy ? con->proxy->port : u->port;
287 char *logname = user;
291 /* If proxy is in use, log in as username@target-site. */
292 logname = concat_strings (user, "@", u->host, (char *) 0);
295 /* Login to the server: */
297 /* First: Establish the control connection. */
299 csock = connect_to_host (host, port);
303 return (retryable_socket_connect_error (errno)
304 ? CONERROR : CONIMPOSSIBLE);
306 if (cmd & LEAVE_PENDING)
311 /* Second: Login with proper USER/PASS sequence. */
312 logprintf (LOG_VERBOSE, _("Logging in as %s ... "),
313 quotearg_style (escape_quoting_style, user));
314 if (opt.server_response)
315 logputs (LOG_ALWAYS, "\n");
316 err = ftp_login (csock, logname, passwd);
321 /* FTPRERR, FTPSRVERR, WRITEFAILED, FTPLOGREFUSED, FTPLOGINC */
325 logputs (LOG_VERBOSE, "\n");
326 logputs (LOG_NOTQUIET, _("\
327 Error in server response, closing control connection.\n"));
332 logputs (LOG_VERBOSE, "\n");
333 logputs (LOG_NOTQUIET, _("Error in server greeting.\n"));
338 logputs (LOG_VERBOSE, "\n");
339 logputs (LOG_NOTQUIET,
340 _("Write failed, closing control connection.\n"));
345 logputs (LOG_VERBOSE, "\n");
346 logputs (LOG_NOTQUIET, _("The server refuses login.\n"));
349 return FTPLOGREFUSED;
351 logputs (LOG_VERBOSE, "\n");
352 logputs (LOG_NOTQUIET, _("Login incorrect.\n"));
357 if (!opt.server_response)
358 logputs (LOG_VERBOSE, _("Logged in!\n"));
363 /* Third: Get the system type */
364 if (!opt.server_response)
365 logprintf (LOG_VERBOSE, "==> SYST ... ");
366 err = ftp_syst (csock, &con->rs);
371 logputs (LOG_VERBOSE, "\n");
372 logputs (LOG_NOTQUIET, _("\
373 Error in server response, closing control connection.\n"));
378 logputs (LOG_VERBOSE, "\n");
379 logputs (LOG_NOTQUIET,
380 _("Server error, can't determine system type.\n"));
383 /* 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"));
407 /* PWD unsupported -- assume "/". */
408 xfree_null (con->id);
409 con->id = xstrdup ("/");
412 /* Everything is OK. */
420 Don't help me out. Please.
421 A reasonably recent VMS FTP server will cope just fine with
422 UNIX file specifications. This code just spoils things.
423 Discarding the device name, for example, is not a wise move.
424 This code was disabled but left in as an example of what not
428 /* VMS will report something like "PUB$DEVICE:[INITIAL.FOLDER]".
429 Convert it to "/INITIAL/FOLDER" */
430 if (con->rs == ST_VMS)
432 char *path = strchr (con->id, '[');
433 char *pathend = path ? strchr (path + 1, ']') : NULL;
434 if (!path || !pathend)
435 DEBUGP (("Initial VMS directory not in the form [...]!\n"));
438 char *idir = con->id;
439 DEBUGP (("Preprocessing the initial VMS directory\n"));
440 DEBUGP ((" old = '%s'\n", con->id));
441 /* We do the conversion in-place by copying the stuff
442 between [ and ] to the beginning, and changing dots
443 to slashes at the same time. */
445 for (++path; path < pathend; path++, idir++)
446 *idir = *path == '.' ? '/' : *path;
448 DEBUGP ((" new = '%s'\n\n", con->id));
453 if (!opt.server_response)
454 logputs (LOG_VERBOSE, _("done.\n"));
456 /* Fifth: Set the FTP type. */
457 type_char = ftp_process_type (u->params);
458 if (!opt.server_response)
459 logprintf (LOG_VERBOSE, "==> TYPE %c ... ", type_char);
460 err = ftp_type (csock, type_char);
461 /* FTPRERR, WRITEFAILED, FTPUNKNOWNTYPE */
465 logputs (LOG_VERBOSE, "\n");
466 logputs (LOG_NOTQUIET, _("\
467 Error in server response, closing control connection.\n"));
472 logputs (LOG_VERBOSE, "\n");
473 logputs (LOG_NOTQUIET,
474 _("Write failed, closing control connection.\n"));
479 logputs (LOG_VERBOSE, "\n");
480 logprintf (LOG_NOTQUIET,
481 _("Unknown type `%c', closing control connection.\n"),
487 /* Everything is OK. */
492 if (!opt.server_response)
493 logputs (LOG_VERBOSE, _("done. "));
499 logputs (LOG_VERBOSE, _("==> CWD not needed.\n"));
507 char *target = u->dir;
509 DEBUGP (("changing working directory\n"));
511 /* Change working directory. To change to a non-absolute
512 Unix directory, we need to prepend initial directory
513 (con->id) to it. Absolute directories "just work".
515 A relative directory is one that does not begin with '/'
516 and, on non-Unix OS'es, one that doesn't begin with
519 This is not done for OS400, which doesn't use
520 "/"-delimited directories, nor does it support directory
521 hierarchies. "CWD foo" followed by "CWD bar" leaves us
522 in "bar", not in "foo/bar", as would be customary
526 Why is this wise even on UNIX? It certainly fouls VMS.
527 See below for a more reliable, more universal method.
531 I'm not crazy about it either. I'm informed it's useful
532 for misconfigured servers that have some dirs in the path
533 with +x but -r, but this method is not RFC-conformant. I
534 understand the need to deal with crappy server
535 configurations, but it's far better to use the canonical
536 method first, and fall back to kludges second.
540 && !(con->rs != ST_UNIX
541 && c_isalpha (target[0])
543 && (con->rs != ST_OS400)
544 && (con->rs != ST_VMS))
546 int idlen = strlen (con->id);
549 /* Strip trailing slash(es) from con->id. */
550 while (idlen > 0 && con->id[idlen - 1] == '/')
552 p = ntarget = (char *)alloca (idlen + 1 + strlen (u->dir) + 1);
553 memcpy (p, con->id, idlen);
558 DEBUGP (("Prepended initial PWD to relative path:\n"));
559 DEBUGP ((" pwd: '%s'\n old: '%s'\n new: '%s'\n",
560 con->id, target, ntarget));
566 Don't help me out. Please.
567 A reasonably recent VMS FTP server will cope just fine with
568 UNIX file specifications. This code just spoils things.
569 Discarding the device name, for example, is not a wise
571 This code was disabled but left in as an example of what
575 /* If the FTP host runs VMS, we will have to convert the absolute
576 directory path in UNIX notation to absolute directory path in
577 VMS notation as VMS FTP servers do not like UNIX notation of
578 absolute paths. "VMS notation" is [dir.subdir.subsubdir]. */
580 if (con->rs == ST_VMS)
583 char *ntarget = (char *)alloca (strlen (target) + 2);
584 /* We use a converted initial dir, so directories in
585 TARGET will be separated with slashes, something like
586 "/INITIAL/FOLDER/DIR/SUBDIR". Convert that to
587 "[INITIAL.FOLDER.DIR.SUBDIR]". */
588 strcpy (ntarget, target);
589 assert (*ntarget == '/');
591 for (tmpp = ntarget + 1; *tmpp; tmpp++)
596 DEBUGP (("Changed file name to VMS syntax:\n"));
597 DEBUGP ((" Unix: '%s'\n VMS: '%s'\n", target, ntarget));
603 A relative directory is relative to the initial directory.
604 Thus, what _is_ useful on VMS (and probably elsewhere) is
605 to CWD to the initial directory (ideally, whatever the
606 server reports, _exactly_, NOT badly UNIX-ixed), and then
607 CWD to the (new) relative directory. This should probably
608 be restructured as a function, called once or twice, but
609 I'm lazy enough to take the badly indented loop short-cut
613 /* Decide on one pass (absolute) or two (relative).
614 The VMS restriction may be relaxed when the squirrely code
617 if ((con->rs == ST_VMS) && (target[0] != '/'))
620 DEBUGP (("Using two-step CWD for relative path.\n"));
624 /* Go straight to the target. */
628 /* At least one VMS FTP server (TCPware V5.6-2) can switch to
629 a UNIX emulation mode when given a UNIX-like directory
630 specification (like "a/b/c"). If allowed to continue this
631 way, LIST interpretation will be confused, because the
632 system type (SYST response) will not be re-checked, and
633 future UNIX-format directory listings (for multiple URLs or
634 "-r") will be horribly misinterpreted.
636 The cheap and nasty work-around is to do a "CWD []" after a
637 UNIX-like directory specification is used. (A single-level
638 directory is harmless.) This puts the TCPware server back
639 into VMS mode, and does no harm on other servers.
641 Unlike the rest of this block, this particular behavior
642 _is_ VMS-specific, so it gets its own VMS test.
644 if ((con->rs == ST_VMS) && (strchr( target, '/') != NULL))
647 DEBUGP (("Using extra \"CWD []\" step for VMS server.\n"));
654 /* 2004-09-20 SMS. */
655 /* Sorry about the deviant indenting. Laziness. */
657 for (cwd_count = cwd_start; cwd_count < cwd_end; cwd_count++)
662 /* Step one (optional): Go to the initial directory,
663 exactly as reported by the server.
669 /* Step two: Go to the target directory. (Absolute or
670 relative will work now.)
676 /* Step three (optional): "CWD []" to restore server
687 if (!opt.server_response)
688 logprintf (LOG_VERBOSE, "==> CWD (%d) %s ... ", cwd_count,
689 quotearg_style (escape_quoting_style, target));
690 err = ftp_cwd (csock, target);
691 /* FTPRERR, WRITEFAILED, FTPNSFOD */
695 logputs (LOG_VERBOSE, "\n");
696 logputs (LOG_NOTQUIET, _("\
697 Error in server response, closing control connection.\n"));
702 logputs (LOG_VERBOSE, "\n");
703 logputs (LOG_NOTQUIET,
704 _("Write failed, closing control connection.\n"));
709 logputs (LOG_VERBOSE, "\n");
710 logprintf (LOG_NOTQUIET, _("No such directory %s.\n\n"),
720 if (!opt.server_response)
721 logputs (LOG_VERBOSE, _("done.\n"));
725 /* 2004-09-20 SMS. */
726 /* End of deviant indenting. */
730 else /* do not CWD */
731 logputs (LOG_VERBOSE, _("==> CWD not required.\n"));
733 if ((cmd & DO_RETR) && *len == 0)
737 if (!opt.server_response)
738 logprintf (LOG_VERBOSE, "==> SIZE %s ... ",
739 quotearg_style (escape_quoting_style, u->file));
742 err = ftp_size (csock, u->file, len);
748 logputs (LOG_VERBOSE, "\n");
749 logputs (LOG_NOTQUIET, _("\
750 Error in server response, closing control connection.\n"));
755 /* Everything is OK. */
760 if (!opt.server_response)
761 logprintf (LOG_VERBOSE, *len ? "%s\n" : _("done.\n"),
762 number_to_static_string (*len));
765 /* If anything is to be retrieved, PORT (or PASV) must be sent. */
766 if (cmd & (DO_LIST | DO_RETR))
770 ip_address passive_addr;
772 err = ftp_do_pasv (csock, &passive_addr, &passive_port);
773 /* FTPRERR, WRITEFAILED, FTPNOPASV, FTPINVPASV */
777 logputs (LOG_VERBOSE, "\n");
778 logputs (LOG_NOTQUIET, _("\
779 Error in server response, closing control connection.\n"));
784 logputs (LOG_VERBOSE, "\n");
785 logputs (LOG_NOTQUIET,
786 _("Write failed, closing control connection.\n"));
791 logputs (LOG_VERBOSE, "\n");
792 logputs (LOG_NOTQUIET, _("Cannot initiate PASV transfer.\n"));
795 logputs (LOG_VERBOSE, "\n");
796 logputs (LOG_NOTQUIET, _("Cannot parse PASV response.\n"));
805 DEBUGP (("trying to connect to %s port %d\n",
806 print_address (&passive_addr), passive_port));
807 dtsock = connect_to_ip (&passive_addr, passive_port, NULL);
810 int save_errno = errno;
813 logprintf (LOG_VERBOSE, _("couldn't connect to %s port %d: %s\n"),
814 print_address (&passive_addr), passive_port,
815 strerror (save_errno));
816 return (retryable_socket_connect_error (save_errno)
817 ? CONERROR : CONIMPOSSIBLE);
820 pasv_mode_open = true; /* Flag to avoid accept port */
821 if (!opt.server_response)
822 logputs (LOG_VERBOSE, _("done. "));
826 if (!pasv_mode_open) /* Try to use a port command if PASV failed */
828 err = ftp_do_port (csock, &local_sock);
829 /* FTPRERR, WRITEFAILED, bindport (FTPSYSERR), HOSTERR,
834 logputs (LOG_VERBOSE, "\n");
835 logputs (LOG_NOTQUIET, _("\
836 Error in server response, closing control connection.\n"));
840 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);
852 logputs (LOG_VERBOSE, "\n");
853 logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
857 fd_close (local_sock);
860 logputs (LOG_VERBOSE, "\n");
861 logprintf (LOG_NOTQUIET, _("Bind error (%s).\n"),
866 logputs (LOG_VERBOSE, "\n");
867 logputs (LOG_NOTQUIET, _("Invalid PORT.\n"));
871 fd_close (local_sock);
878 if (!opt.server_response)
879 logputs (LOG_VERBOSE, _("done. "));
881 } /* cmd & (DO_LIST | DO_RETR) */
883 /* Restart if needed. */
884 if (restval && (cmd & DO_RETR))
886 if (!opt.server_response)
887 logprintf (LOG_VERBOSE, "==> REST %s ... ",
888 number_to_static_string (restval));
889 err = ftp_rest (csock, restval);
891 /* FTPRERR, WRITEFAILED, FTPRESTFAIL */
895 logputs (LOG_VERBOSE, "\n");
896 logputs (LOG_NOTQUIET, _("\
897 Error in server response, closing control connection.\n"));
901 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);
913 logputs (LOG_VERBOSE, _("\nREST failed, starting from scratch.\n"));
921 if (err != FTPRESTFAIL && !opt.server_response)
922 logputs (LOG_VERBOSE, _("done. "));
923 } /* restval && cmd & DO_RETR */
927 /* If we're in spider mode, don't really retrieve anything except
928 the directory listing and verify whether the given "file" exists. */
934 res = ftp_get_listing (u, con, &f);
935 /* Set the DO_RETR command flag again, because it gets unset when
936 calling ftp_get_listing() and would otherwise cause an assertion
937 failure earlier on when this function gets repeatedly called
938 (e.g., when recursing). */
944 if (!strcmp (f->name, u->file))
953 logputs (LOG_VERBOSE, "\n");
954 logprintf (LOG_NOTQUIET, _("File %s exists.\n"),
959 logputs (LOG_VERBOSE, "\n");
960 logprintf (LOG_NOTQUIET, _("No such file %s.\n"),
967 fd_close (local_sock);
973 if (!opt.server_response)
976 logputs (LOG_VERBOSE, "\n");
977 logprintf (LOG_VERBOSE, "==> RETR %s ... ",
978 quotearg_style (escape_quoting_style, u->file));
982 err = ftp_retr (csock, u->file);
983 /* FTPRERR, WRITEFAILED, FTPNSFOD */
987 logputs (LOG_VERBOSE, "\n");
988 logputs (LOG_NOTQUIET, _("\
989 Error in server response, closing control connection.\n"));
993 fd_close (local_sock);
996 logputs (LOG_VERBOSE, "\n");
997 logputs (LOG_NOTQUIET,
998 _("Write failed, closing control connection.\n"));
1002 fd_close (local_sock);
1005 logputs (LOG_VERBOSE, "\n");
1006 logprintf (LOG_NOTQUIET, _("No such file %s.\n\n"),
1009 fd_close (local_sock);
1017 if (!opt.server_response)
1018 logputs (LOG_VERBOSE, _("done.\n"));
1019 expected_bytes = ftp_expected_bytes (ftp_last_respline);
1024 if (!opt.server_response)
1025 logputs (LOG_VERBOSE, "==> LIST ... ");
1026 /* As Maciej W. Rozycki (macro@ds2.pg.gda.pl) says, `LIST'
1027 without arguments is better than `LIST .'; confirmed by
1029 err = ftp_list (csock, NULL, con->rs);
1030 /* FTPRERR, WRITEFAILED */
1034 logputs (LOG_VERBOSE, "\n");
1035 logputs (LOG_NOTQUIET, _("\
1036 Error in server response, closing control connection.\n"));
1040 fd_close (local_sock);
1043 logputs (LOG_VERBOSE, "\n");
1044 logputs (LOG_NOTQUIET,
1045 _("Write failed, closing control connection.\n"));
1049 fd_close (local_sock);
1052 logputs (LOG_VERBOSE, "\n");
1053 logprintf (LOG_NOTQUIET, _("No such file or directory %s.\n\n"),
1056 fd_close (local_sock);
1063 if (!opt.server_response)
1064 logputs (LOG_VERBOSE, _("done.\n"));
1065 expected_bytes = ftp_expected_bytes (ftp_last_respline);
1066 } /* cmd & DO_LIST */
1068 if (!(cmd & (DO_LIST | DO_RETR)) || (opt.spider && !(cmd & DO_LIST)))
1069 return RETRFINISHED;
1071 /* Some FTP servers return the total length of file after REST
1072 command, others just return the remaining size. */
1073 if (*len && restval && expected_bytes
1074 && (expected_bytes == *len - restval))
1076 DEBUGP (("Lying FTP server found, adjusting.\n"));
1077 expected_bytes = *len;
1080 /* If no transmission was required, then everything is OK. */
1081 if (!pasv_mode_open) /* we are not using pasive mode so we need
1084 /* Wait for the server to connect to the address we're waiting
1086 dtsock = accept_connection (local_sock);
1089 logprintf (LOG_NOTQUIET, "accept: %s\n", strerror (errno));
1094 /* Open the file -- if output_stream is set, use it instead. */
1097 Note that having the output_stream ("-O") file opened in main()
1098 (main.c) rather limits the ability in VMS to open the file
1099 differently for ASCII versus binary FTP here. (Of course, doing it
1100 there allows a open failure to be detected immediately, without first
1101 connecting to the server.)
1103 if (!output_stream || con->cmd & DO_LIST)
1105 /* On VMS, alter the name as required. */
1109 targ = ods_conform (con->target);
1110 if (targ != con->target)
1112 xfree (con->target);
1115 #endif /* def __VMS */
1117 mkalldirs (con->target);
1119 rotate_backups (con->target);
1122 For VMS, define common fopen() optional arguments, and a handy macro
1123 for use as a variable "binary" flag.
1124 Elsewhere, define a constant "binary" flag.
1125 Isn't it nice to have distinct text and binary file types?
1127 # define BIN_TYPE_TRANSFER (type_char != 'A')
1129 # define FOPEN_OPT_ARGS "fop=sqo", "acc", acc_cb, &open_id
1130 # define FOPEN_OPT_ARGS_BIN "ctx=bin,stm", "rfm=fix", "mrs=512" FOPEN_OPT_ARGS
1131 # define BIN_TYPE_FILE (BIN_TYPE_TRANSFER && (opt.ftp_stmlf == 0))
1132 #else /* def __VMS */
1133 # define BIN_TYPE_FILE 1
1134 #endif /* def __VMS [else] */
1136 if (restval && !(con->cmd & DO_LIST))
1144 fp = fopen (con->target, "ab", FOPEN_OPT_ARGS_BIN);
1149 fp = fopen (con->target, "a", FOPEN_OPT_ARGS);
1151 #else /* def __VMS */
1152 fp = fopen (con->target, "ab");
1153 #endif /* def __VMS [else] */
1155 else if (opt.noclobber || opt.always_rest || opt.timestamping || opt.dirstruct
1156 || opt.output_document)
1164 fp = fopen (con->target, "wb", FOPEN_OPT_ARGS_BIN);
1169 fp = fopen (con->target, "w", FOPEN_OPT_ARGS);
1171 #else /* def __VMS */
1172 fp = fopen (con->target, "wb");
1173 #endif /* def __VMS [else] */
1177 fp = fopen_excl (con->target, true);
1178 if (!fp && errno == EEXIST)
1180 /* We cannot just invent a new name and use it (which is
1181 what functions like unique_create typically do)
1182 because we told the user we'd use this name.
1183 Instead, return and retry the download. */
1184 logprintf (LOG_NOTQUIET, _("%s has sprung into existence.\n"),
1189 fd_close (local_sock);
1190 return FOPEN_EXCL_ERR;
1195 logprintf (LOG_NOTQUIET, "%s: %s\n", con->target, strerror (errno));
1199 fd_close (local_sock);
1208 print_length (*len, restval, true);
1209 expected_bytes = *len; /* for fd_read_body's progress bar */
1211 else if (expected_bytes)
1212 print_length (expected_bytes, restval, false);
1214 /* Get the contents of the document. */
1216 if (restval && rest_failed)
1217 flags |= rb_skip_startpos;
1220 res = fd_read_body (dtsock, fp,
1221 expected_bytes ? expected_bytes - restval : 0,
1222 restval, &rd_size, len, &con->dltime, flags);
1224 tms = datetime_str (time (NULL));
1225 tmrate = retr_rate (rd_size, con->dltime);
1226 total_download_time += con->dltime;
1228 fd_close (local_sock);
1229 /* Close the local file. */
1230 if (!output_stream || con->cmd & DO_LIST)
1233 /* If fd_read_body couldn't write to fp, bail out. */
1236 logprintf (LOG_NOTQUIET, _("%s: %s, closing control connection.\n"),
1237 con->target, strerror (errno));
1245 logprintf (LOG_NOTQUIET, _("%s (%s) - Data connection: %s; "),
1246 tms, tmrate, fd_errstr (dtsock));
1247 if (opt.server_response)
1248 logputs (LOG_ALWAYS, "\n");
1252 /* Get the server to tell us if everything is retrieved. */
1253 err = ftp_response (csock, &respline);
1256 /* The control connection is decidedly closed. Print the time
1257 only if it hasn't already been printed. */
1259 logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
1260 logputs (LOG_NOTQUIET, _("Control connection closed.\n"));
1261 /* If there is an error on the control connection, close it, but
1262 return FTPRETRINT, since there is a possibility that the
1263 whole file was retrieved nevertheless (but that is for
1264 ftp_loop_internal to decide). */
1268 } /* err != FTPOK */
1269 /* If retrieval failed for any reason, return FTPRETRINT, but do not
1270 close socket, since the control connection is still alive. If
1271 there is something wrong with the control connection, it will
1272 become apparent later. */
1273 if (*respline != '2')
1277 logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
1278 logputs (LOG_NOTQUIET, _("Data transfer aborted.\n"));
1285 /* What now? The data connection was erroneous, whereas the
1286 response says everything is OK. We shall play it safe. */
1290 if (!(cmd & LEAVE_PENDING))
1292 /* Closing the socket is faster than sending 'QUIT' and the
1293 effect is the same. */
1297 /* If it was a listing, and opt.server_response is true,
1299 if (opt.server_response && (con->cmd & DO_LIST))
1302 Much of this work may already have been done, but repeating it should
1303 do no damage beyond wasting time.
1305 /* On VMS, alter the name as required. */
1309 targ = ods_conform( con->target);
1310 if (targ != con->target)
1312 xfree( con->target);
1315 #endif /* def __VMS */
1317 mkalldirs (con->target);
1318 fp = fopen (con->target, "r");
1320 logprintf (LOG_ALWAYS, "%s: %s\n", con->target, strerror (errno));
1324 /* The lines are being read with read_whole_line because of
1325 no-buffering on opt.lfile. */
1326 while ((line = read_whole_line (fp)) != NULL)
1328 char *p = strchr (line, '\0');
1329 while (p > line && (p[-1] == '\n' || p[-1] == '\r'))
1331 logprintf (LOG_ALWAYS, "%s\n",
1332 quotearg_style (escape_quoting_style, line));
1337 } /* con->cmd & DO_LIST && server_response */
1339 return RETRFINISHED;
1342 /* A one-file FTP loop. This is the part where FTP retrieval is
1343 retried, and retried, and retried, and...
1345 This loop either gets commands from con, or (if ON_YOUR_OWN is
1346 set), makes them up to retrieve the file given by the URL. */
1348 ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
1351 wgint restval, len = 0;
1353 const char *tmrate = NULL;
1357 /* Get the target, and set the name for the message accordingly. */
1358 if ((f == NULL) && (con->target))
1360 /* Explicit file (like ".listing"). */
1365 /* URL-derived file. Consider "-O file" name. */
1366 con->target = url_file_name (u);
1367 if (!opt.output_document)
1370 locf = opt.output_document;
1373 /* If the output_document was given, then this check was already done and
1374 the file didn't exist. Hence the !opt.output_document */
1375 if (opt.noclobber && !opt.output_document && file_exists_p (con->target))
1377 logprintf (LOG_VERBOSE,
1378 _("File %s already there; not retrieving.\n"), quote (con->target));
1379 /* If the file is there, we suppose it's retrieved OK. */
1383 /* Remove it if it's a link. */
1384 remove_link (con->target);
1388 if (con->st & ON_YOUR_OWN)
1389 con->st = ON_YOUR_OWN;
1391 orig_lp = con->cmd & LEAVE_PENDING ? 1 : 0;
1396 /* Increment the pass counter. */
1398 sleep_between_retrievals (count);
1399 if (con->st & ON_YOUR_OWN)
1402 con->cmd |= (DO_RETR | LEAVE_PENDING);
1403 if (con->csock != -1)
1404 con->cmd &= ~ (DO_LOGIN | DO_CWD);
1406 con->cmd |= (DO_LOGIN | DO_CWD);
1408 else /* not on your own */
1410 if (con->csock != -1)
1411 con->cmd &= ~DO_LOGIN;
1413 con->cmd |= DO_LOGIN;
1414 if (con->st & DONE_CWD)
1415 con->cmd &= ~DO_CWD;
1420 /* Decide whether or not to restart. */
1421 if (con->cmd & DO_LIST)
1423 else if (opt.always_rest
1424 && stat (locf, &st) == 0
1425 && S_ISREG (st.st_mode))
1426 /* When -c is used, continue from on-disk size. (Can't use
1427 hstat.len even if count>1 because we don't want a failed
1428 first attempt to clobber existing data.) */
1429 restval = st.st_size;
1431 restval = len; /* start where the previous run left off */
1435 /* Get the current time string. */
1436 tms = datetime_str (time (NULL));
1437 /* Print fetch message, if opt.verbose. */
1440 char *hurl = url_string (u, URL_AUTH_HIDE_PASSWD);
1444 sprintf (tmp, _("(try:%2d)"), count);
1445 logprintf (LOG_VERBOSE, "--%s-- %s\n %s => %s\n",
1446 tms, hurl, tmp, quote (locf));
1448 ws_changetitle (hurl);
1452 /* Send getftp the proper length, if fileinfo was provided. */
1457 err = getftp (u, &len, restval, con);
1459 if (con->csock == -1)
1460 con->st &= ~DONE_CWD;
1462 con->st |= DONE_CWD;
1466 case HOSTERR: case CONIMPOSSIBLE: case FWRITEERR: case FOPENERR:
1467 case FTPNSFOD: case FTPLOGINC: case FTPNOPASV: case CONTNOTSUPPORTED:
1468 /* Fatal errors, give up. */
1470 case CONSOCKERR: case CONERROR: case FTPSRVERR: case FTPRERR:
1471 case WRITEFAILED: case FTPUNKNOWNTYPE: case FTPSYSERR:
1472 case FTPPORTERR: case FTPLOGREFUSED: case FTPINVPASV:
1473 case FOPEN_EXCL_ERR:
1474 printwhat (count, opt.ntry);
1475 /* non-fatal errors */
1476 if (err == FOPEN_EXCL_ERR)
1478 /* Re-determine the file name. */
1479 xfree_null (con->target);
1480 con->target = url_file_name (u);
1485 /* If the control connection was closed, the retrieval
1486 will be considered OK if f->size == len. */
1487 if (!f || len != f->size)
1489 printwhat (count, opt.ntry);
1500 tms = datetime_str (time (NULL));
1502 tmrate = retr_rate (len - restval, con->dltime);
1504 /* If we get out of the switch above without continue'ing, we've
1505 successfully downloaded a file. Remember this fact. */
1506 downloaded_file (FILE_DOWNLOADED_NORMALLY, locf);
1508 if (con->st & ON_YOUR_OWN)
1510 fd_close (con->csock);
1515 bool write_to_stdout = (opt.output_document && HYPHENP (opt.output_document));
1517 logprintf (LOG_VERBOSE,
1519 ? _("%s (%s) - written to stdout %s[%s]\n\n")
1520 : _("%s (%s) - %s saved [%s]\n\n"),
1522 write_to_stdout ? "" : quote (locf),
1523 number_to_static_string (len));
1525 if (!opt.verbose && !opt.quiet)
1527 /* Need to hide the password from the URL. The `if' is here
1528 so that we don't do the needless allocation every
1530 char *hurl = url_string (u, URL_AUTH_HIDE_PASSWD);
1531 logprintf (LOG_NONVERBOSE, "%s URL: %s [%s] -> \"%s\" [%d]\n",
1532 tms, hurl, number_to_static_string (len), locf, count);
1536 if ((con->cmd & DO_LIST))
1537 /* This is a directory listing file. */
1539 if (!opt.remove_listing)
1540 /* --dont-remove-listing was specified, so do count this towards the
1541 number of bytes and files downloaded. */
1543 total_downloaded_bytes += len;
1547 /* Deletion of listing files is not controlled by --delete-after, but
1548 by the more specific option --dont-remove-listing, and the code
1549 to do this deletion is in another function. */
1551 else if (!opt.spider)
1552 /* This is not a directory listing file. */
1554 /* Unlike directory listing files, don't pretend normal files weren't
1555 downloaded if they're going to be deleted. People seeding proxies,
1556 for instance, may want to know how many bytes and files they've
1557 downloaded through it. */
1558 total_downloaded_bytes += len;
1561 if (opt.delete_after)
1564 Removing file due to --delete-after in ftp_loop_internal():\n"));
1565 logprintf (LOG_VERBOSE, _("Removing %s.\n"), locf);
1567 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1571 /* Restore the original leave-pendingness. */
1573 con->cmd |= LEAVE_PENDING;
1575 con->cmd &= ~LEAVE_PENDING;
1577 } while (!opt.ntry || (count < opt.ntry));
1579 if (con->csock != -1 && (con->st & ON_YOUR_OWN))
1581 fd_close (con->csock);
1587 /* Return the directory listing in a reusable format. The directory
1588 is specifed in u->dir. */
1590 ftp_get_listing (struct url *u, ccon *con, struct fileinfo **f)
1593 char *uf; /* url file name */
1594 char *lf; /* list file name */
1595 char *old_target = con->target;
1597 con->st &= ~ON_YOUR_OWN;
1598 con->cmd |= (DO_LIST | LEAVE_PENDING);
1599 con->cmd &= ~DO_RETR;
1601 /* Find the listing file name. We do it by taking the file name of
1602 the URL and replacing the last component with the listing file
1604 uf = url_file_name (u);
1605 lf = file_merge (uf, LIST_FILENAME);
1607 DEBUGP ((_("Using %s as listing tmp file.\n"), quote (lf)));
1609 con->target = xstrdup (lf);
1611 err = ftp_loop_internal (u, NULL, con);
1612 lf = xstrdup (con->target);
1613 xfree (con->target);
1614 con->target = old_target;
1618 *f = ftp_parse_ls (lf, con->rs);
1619 if (opt.remove_listing)
1622 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1624 logprintf (LOG_VERBOSE, _("Removed %s.\n"), quote (lf));
1630 con->cmd &= ~DO_LIST;
1634 static uerr_t ftp_retrieve_dirs (struct url *, struct fileinfo *, ccon *);
1635 static uerr_t ftp_retrieve_glob (struct url *, ccon *, int);
1636 static struct fileinfo *delelement (struct fileinfo *, struct fileinfo **);
1637 static void freefileinfo (struct fileinfo *f);
1639 /* Retrieve a list of files given in struct fileinfo linked list. If
1640 a file is a symbolic link, do not retrieve it, but rather try to
1641 set up a similar link on the local disk, if the symlinks are
1644 If opt.recursive is set, after all files have been retrieved,
1645 ftp_retrieve_dirs will be called to retrieve the directories. */
1647 ftp_retrieve_list (struct url *u, struct fileinfo *f, ccon *con)
1649 static int depth = 0;
1651 struct fileinfo *orig;
1654 bool dlthis; /* Download this (file). */
1655 const char *actual_target = NULL;
1657 /* Increase the depth. */
1659 if (opt.reclevel != INFINITE_RECURSION && depth > opt.reclevel)
1661 DEBUGP ((_("Recursion depth %d exceeded max. depth %d.\n"),
1662 depth, opt.reclevel));
1670 con->st &= ~ON_YOUR_OWN;
1671 if (!(con->st & DONE_CWD))
1674 con->cmd &= ~DO_CWD;
1675 con->cmd |= (DO_RETR | LEAVE_PENDING);
1678 con->cmd |= DO_LOGIN;
1680 con->cmd &= ~DO_LOGIN;
1682 err = RETROK; /* in case it's not used */
1686 char *old_target, *ofile;
1688 if (opt.quota && total_downloaded_bytes > opt.quota)
1693 old_target = con->target;
1695 ofile = xstrdup (u->file);
1696 url_set_file (u, f->name);
1698 con->target = url_file_name (u);
1702 if (opt.timestamping && f->type == FT_PLAINFILE)
1705 /* If conversion of HTML files retrieved via FTP is ever implemented,
1706 we'll need to stat() <file>.orig here when -K has been specified.
1707 I'm not implementing it now since files on an FTP server are much
1708 more likely than files on an HTTP server to legitimately have a
1710 if (!stat (con->target, &st))
1714 /* Else, get it from the file. */
1715 local_size = st.st_size;
1718 /* Modification time granularity is 2 seconds for Windows, so
1719 increase local time by 1 second for later comparison. */
1722 /* Compare file sizes only for servers that tell us correct
1723 values. Assume sizes being equal for servers that lie
1725 cor_val = (con->rs == ST_UNIX || con->rs == ST_WINNT);
1726 eq_size = cor_val ? (local_size == f->size) : true;
1727 if (f->tstamp <= tml && eq_size)
1729 /* Remote file is older, file sizes can be compared and
1731 logprintf (LOG_VERBOSE, _("\
1732 Remote file no newer than local file %s -- not retrieving.\n"), quote (con->target));
1737 /* Remote file is newer or sizes cannot be matched */
1738 logprintf (LOG_VERBOSE, _("\
1739 Remote file is newer than local file %s -- retrieving.\n\n"),
1740 quote (con->target));
1744 /* Sizes do not match */
1745 logprintf (LOG_VERBOSE, _("\
1746 The sizes do not match (local %s) -- retrieving.\n\n"),
1747 number_to_static_string (local_size));
1750 } /* opt.timestamping && f->type == FT_PLAINFILE */
1754 /* If opt.retr_symlinks is defined, we treat symlinks as
1755 if they were normal files. There is currently no way
1756 to distinguish whether they might be directories, and
1758 if (!opt.retr_symlinks)
1762 logputs (LOG_NOTQUIET,
1763 _("Invalid name of the symlink, skipping.\n"));
1767 /* Check whether we already have the correct
1769 int rc = lstat (con->target, &st);
1772 size_t len = strlen (f->linkto) + 1;
1773 if (S_ISLNK (st.st_mode))
1775 char *link_target = (char *)alloca (len);
1776 size_t n = readlink (con->target, link_target, len);
1778 && (memcmp (link_target, f->linkto, n) == 0))
1780 logprintf (LOG_VERBOSE, _("\
1781 Already have correct symlink %s -> %s\n\n"),
1782 quote (con->target),
1789 logprintf (LOG_VERBOSE, _("Creating symlink %s -> %s\n"),
1790 quote (con->target), quote (f->linkto));
1791 /* Unlink before creating symlink! */
1792 unlink (con->target);
1793 if (symlink (f->linkto, con->target) == -1)
1794 logprintf (LOG_NOTQUIET, "symlink: %s\n", strerror (errno));
1795 logputs (LOG_VERBOSE, "\n");
1796 } /* have f->linkto */
1797 #else /* not HAVE_SYMLINK */
1798 logprintf (LOG_NOTQUIET,
1799 _("Symlinks not supported, skipping symlink %s.\n"),
1800 quote (con->target));
1801 #endif /* not HAVE_SYMLINK */
1803 else /* opt.retr_symlinks */
1806 err = ftp_loop_internal (u, f, con);
1807 } /* opt.retr_symlinks */
1811 logprintf (LOG_NOTQUIET, _("Skipping directory %s.\n"),
1815 /* Call the retrieve loop. */
1817 err = ftp_loop_internal (u, f, con);
1820 logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
1827 * Set permissions _before_ setting the times, as setting the
1828 * permissions changes the modified-time, at least on VMS.
1829 * Also, use the opt.output_document name here, too, as
1830 * appropriate. (Do the test once, and save the result.)
1833 set_local_file (&actual_target, con->target);
1835 /* If downloading a plain file, set valid (non-zero) permissions. */
1836 if (dlthis && (actual_target != NULL) && (f->type == FT_PLAINFILE))
1839 chmod (actual_target, f->perms);
1841 DEBUGP (("Unrecognized permissions for %s.\n", actual_target));
1844 /* Set the time-stamp information to the local file. Symlinks
1845 are not to be stamped because it sets the stamp on the
1847 if (actual_target != NULL)
1849 if (!(f->type == FT_SYMLINK && !opt.retr_symlinks)
1852 && file_exists_p (con->target))
1854 touch (actual_target, f->tstamp);
1856 else if (f->tstamp == -1)
1857 logprintf (LOG_NOTQUIET, _("%s: corrupt time-stamp.\n"),
1861 xfree (con->target);
1862 con->target = old_target;
1864 url_set_file (u, ofile);
1867 /* Break on fatals. */
1868 if (err == QUOTEXC || err == HOSTERR || err == FWRITEERR)
1870 con->cmd &= ~ (DO_CWD | DO_LOGIN);
1874 /* We do not want to call ftp_retrieve_dirs here */
1875 if (opt.recursive &&
1876 !(opt.reclevel != INFINITE_RECURSION && depth >= opt.reclevel))
1877 err = ftp_retrieve_dirs (u, orig, con);
1878 else if (opt.recursive)
1879 DEBUGP ((_("Will not retrieve dirs since depth is %d (max %d).\n"),
1880 depth, opt.reclevel));
1885 /* Retrieve the directories given in a file list. This function works
1886 by simply going through the linked list and calling
1887 ftp_retrieve_glob on each directory entry. The function knows
1888 about excluded directories. */
1890 ftp_retrieve_dirs (struct url *u, struct fileinfo *f, ccon *con)
1892 char *container = NULL;
1893 int container_size = 0;
1895 for (; f; f = f->next)
1898 char *odir, *newdir;
1900 if (opt.quota && total_downloaded_bytes > opt.quota)
1902 if (f->type != FT_DIRECTORY)
1905 /* Allocate u->dir off stack, but reallocate only if a larger
1906 string is needed. It's a pity there's no "realloca" for an
1907 item on the bottom of the stack. */
1908 size = strlen (u->dir) + 1 + strlen (f->name) + 1;
1909 if (size > container_size)
1910 container = (char *)alloca (size);
1915 || (*odir == '/' && *(odir + 1) == '\0'))
1916 /* If ODIR is empty or just "/", simply append f->name to
1917 ODIR. (In the former case, to preserve u->dir being
1918 relative; in the latter case, to avoid double slash.) */
1919 sprintf (newdir, "%s%s", odir, f->name);
1921 /* Else, use a separator. */
1922 sprintf (newdir, "%s/%s", odir, f->name);
1924 DEBUGP (("Composing new CWD relative to the initial directory.\n"));
1925 DEBUGP ((" odir = '%s'\n f->name = '%s'\n newdir = '%s'\n\n",
1926 odir, f->name, newdir));
1927 if (!accdir (newdir))
1929 logprintf (LOG_VERBOSE, _("\
1930 Not descending to %s as it is excluded/not-included.\n"),
1935 con->st &= ~DONE_CWD;
1937 odir = xstrdup (u->dir); /* because url_set_dir will free
1939 url_set_dir (u, newdir);
1940 ftp_retrieve_glob (u, con, GLOB_GETALL);
1941 url_set_dir (u, odir);
1944 /* Set the time-stamp? */
1947 if (opt.quota && total_downloaded_bytes > opt.quota)
1953 /* Return true if S has a leading '/' or contains '../' */
1955 has_insecure_name_p (const char *s)
1960 if (strstr (s, "../") != 0)
1966 /* A near-top-level function to retrieve the files in a directory.
1967 The function calls ftp_get_listing, to get a linked list of files.
1968 Then it weeds out the file names that do not match the pattern.
1969 ftp_retrieve_list is called with this updated list as an argument.
1971 If the argument ACTION is GLOB_GETONE, just download the file (but
1972 first get the listing, so that the time-stamp is heeded); if it's
1973 GLOB_GLOBALL, use globbing; if it's GLOB_GETALL, download the whole
1976 ftp_retrieve_glob (struct url *u, ccon *con, int action)
1978 struct fileinfo *f, *start;
1981 con->cmd |= LEAVE_PENDING;
1983 res = ftp_get_listing (u, con, &start);
1986 /* First: weed out that do not conform the global rules given in
1987 opt.accepts and opt.rejects. */
1988 if (opt.accepts || opt.rejects)
1993 if (f->type != FT_DIRECTORY && !acceptable (f->name))
1995 logprintf (LOG_VERBOSE, _("Rejecting %s.\n"),
1997 f = delelement (f, &start);
2003 /* Remove all files with possible harmful names */
2007 if (has_insecure_name_p (f->name))
2009 logprintf (LOG_VERBOSE, _("Rejecting %s.\n"),
2011 f = delelement (f, &start);
2016 /* Now weed out the files that do not match our globbing pattern.
2017 If we are dealing with a globbing pattern, that is. */
2020 if (action == GLOB_GLOBALL)
2022 int (*matcher) (const char *, const char *, int)
2023 = opt.ignore_case ? fnmatch_nocase : fnmatch;
2029 matchres = matcher (u->file, f->name, 0);
2032 logprintf (LOG_NOTQUIET, _("Error matching %s against %s: %s\n"),
2033 u->file, quotearg_style (escape_quoting_style, f->name),
2037 if (matchres == FNM_NOMATCH)
2038 f = delelement (f, &start); /* delete the element from the list */
2040 f = f->next; /* leave the element in the list */
2044 freefileinfo (start);
2045 return RETRBADPATTERN;
2048 else if (action == GLOB_GETONE)
2050 int (*cmp) (const char *, const char *)
2051 = opt.ignore_case ? strcasecmp : strcmp;
2055 if (0 != cmp(u->file, f->name))
2056 f = delelement (f, &start);
2064 /* Just get everything. */
2065 ftp_retrieve_list (u, start, con);
2069 if (action == GLOB_GLOBALL)
2072 /* #### This message SUCKS. We should see what was the
2073 reason that nothing was retrieved. */
2074 logprintf (LOG_VERBOSE, _("No matches on pattern %s.\n"),
2077 else if (action == GLOB_GETONE) /* GLOB_GETONE or GLOB_GETALL */
2079 /* Let's try retrieving it anyway. */
2080 con->st |= ON_YOUR_OWN;
2081 res = ftp_loop_internal (u, NULL, con);
2085 /* If action == GLOB_GETALL, and the file list is empty, there's
2086 no point in trying to download anything or in complaining about
2087 it. (An empty directory should not cause complaints.)
2090 freefileinfo (start);
2091 if (opt.quota && total_downloaded_bytes > opt.quota)
2094 /* #### Should we return `res' here? */
2098 /* The wrapper that calls an appropriate routine according to contents
2099 of URL. Inherently, its capabilities are limited on what can be
2100 encoded into a URL. */
2102 ftp_loop (struct url *u, int *dt, struct url *proxy, bool recursive, bool glob)
2104 ccon con; /* FTP connection */
2112 con.st = ON_YOUR_OWN;
2117 /* If the file name is empty, the user probably wants a directory
2118 index. We'll provide one, properly HTML-ized. Unless
2119 opt.htmlify is 0, of course. :-) */
2120 if (!*u->file && !recursive)
2123 res = ftp_get_listing (u, &con, &f);
2127 if (opt.htmlify && !opt.spider)
2129 char *filename = (opt.output_document
2130 ? xstrdup (opt.output_document)
2131 : (con.target ? xstrdup (con.target)
2132 : url_file_name (u)));
2133 res = ftp_index (filename, u, f);
2134 if (res == FTPOK && opt.verbose)
2136 if (!opt.output_document)
2140 if (stat (filename, &st) == 0)
2144 logprintf (LOG_NOTQUIET,
2145 _("Wrote HTML-ized index to %s [%s].\n"),
2146 quote (filename), number_to_static_string (sz));
2149 logprintf (LOG_NOTQUIET,
2150 _("Wrote HTML-ized index to %s.\n"),
2160 bool ispattern = false;
2163 /* Treat the URL as a pattern if the file name part of the
2164 URL path contains wildcards. (Don't check for u->file
2165 because it is unescaped and therefore doesn't leave users
2166 the option to escape literal '*' as %2A.) */
2167 char *file_part = strrchr (u->path, '/');
2169 file_part = u->path;
2170 ispattern = has_wildcards_p (file_part);
2172 if (ispattern || recursive || opt.timestamping)
2174 /* ftp_retrieve_glob is a catch-all function that gets called
2175 if we need globbing, time-stamping or recursion. Its
2176 third argument is just what we really need. */
2177 res = ftp_retrieve_glob (u, &con,
2178 ispattern ? GLOB_GLOBALL : GLOB_GETONE);
2181 res = ftp_loop_internal (u, NULL, &con);
2187 /* If a connection was left, quench it. */
2188 if (con.csock != -1)
2189 fd_close (con.csock);
2190 xfree_null (con.id);
2192 xfree_null (con.target);
2197 /* Delete an element from the fileinfo linked list. Returns the
2198 address of the next element, or NULL if the list is exhausted. It
2199 can modify the start of the list. */
2200 static struct fileinfo *
2201 delelement (struct fileinfo *f, struct fileinfo **start)
2203 struct fileinfo *prev = f->prev;
2204 struct fileinfo *next = f->next;
2207 xfree_null (f->linkto);
2219 /* Free the fileinfo linked list of files. */
2221 freefileinfo (struct fileinfo *f)
2225 struct fileinfo *next = f->next;