]> sjero.net Git - wget/blob - src/ftp.c
"LIST" or "LIST -a" ftp command according to the remote system
[wget] / src / ftp.c
1 /* File Transfer Protocol support.
2    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3    2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
4    Inc.
5
6 This file is part of GNU Wget.
7
8 GNU Wget is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 GNU Wget is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Wget.  If not, see <http://www.gnu.org/licenses/>.
20
21 Additional permission under GNU GPL version 3 section 7
22
23 If you modify this program, or any covered work, by linking or
24 combining it with the OpenSSL project's OpenSSL library (or a
25 modified version of that library), containing parts covered by the
26 terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
27 grants you additional permission to convey the resulting work.
28 Corresponding Source for a non-source form of such a combination
29 shall include the source code for the parts of OpenSSL used as well
30 as that of the covered work.  */
31
32 #include "wget.h"
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <strings.h>
38 #include <unistd.h>
39 #include <assert.h>
40 #include <errno.h>
41 #include <time.h>
42
43 #include "utils.h"
44 #include "url.h"
45 #include "retr.h"
46 #include "ftp.h"
47 #include "connect.h"
48 #include "host.h"
49 #include "netrc.h"
50 #include "convert.h"            /* for downloaded_file */
51 #include "recur.h"              /* for INFINITE_RECURSION */
52 #include "warc.h"
53
54 #ifdef __VMS
55 # include "vms.h"
56 #endif /* def __VMS */
57
58
59 /* File where the "ls -al" listing will be saved.  */
60 #ifdef MSDOS
61 #define LIST_FILENAME "_listing"
62 #else
63 #define LIST_FILENAME ".listing"
64 #endif
65
66 typedef struct
67 {
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   enum ustype rsu;              /* when rs is ST_UNIX, here there are more details */
74   char *id;                     /* initial directory */
75   char *target;                 /* target file name */
76   struct url *proxy;            /* FTWK-style proxy */
77 } ccon;
78
79 extern int numurls;
80
81 /* Look for regexp "( *[0-9]+ *byte" (literal parenthesis) anywhere in
82    the string S, and return the number converted to wgint, if found, 0
83    otherwise.  */
84 static wgint
85 ftp_expected_bytes (const char *s)
86 {
87   wgint res;
88
89   while (1)
90     {
91       while (*s && *s != '(')
92         ++s;
93       if (!*s)
94         return 0;
95       ++s;                      /* skip the '(' */
96       res = str_to_wgint (s, (char **) &s, 10);
97       if (!*s)
98         return 0;
99       while (*s && c_isspace (*s))
100         ++s;
101       if (!*s)
102         return 0;
103       if (c_tolower (*s) != 'b')
104         continue;
105       if (strncasecmp (s, "byte", 4))
106         continue;
107       else
108         break;
109     }
110   return res;
111 }
112
113 #ifdef ENABLE_IPV6
114 /*
115  * This function sets up a passive data connection with the FTP server.
116  * It is merely a wrapper around ftp_epsv, ftp_lpsv and ftp_pasv.
117  */
118 static uerr_t
119 ftp_do_pasv (int csock, ip_address *addr, int *port)
120 {
121   uerr_t err;
122
123   /* We need to determine the address family and need to call
124      getpeername, so while we're at it, store the address to ADDR.
125      ftp_pasv and ftp_lpsv can simply override it.  */
126   if (!socket_ip_address (csock, addr, ENDPOINT_PEER))
127     abort ();
128
129   /* If our control connection is over IPv6, then we first try EPSV and then
130    * LPSV if the former is not supported. If the control connection is over
131    * IPv4, we simply issue the good old PASV request. */
132   switch (addr->family)
133     {
134     case AF_INET:
135       if (!opt.server_response)
136         logputs (LOG_VERBOSE, "==> PASV ... ");
137       err = ftp_pasv (csock, addr, port);
138       break;
139     case AF_INET6:
140       if (!opt.server_response)
141         logputs (LOG_VERBOSE, "==> EPSV ... ");
142       err = ftp_epsv (csock, addr, port);
143
144       /* If EPSV is not supported try LPSV */
145       if (err == FTPNOPASV)
146         {
147           if (!opt.server_response)
148             logputs (LOG_VERBOSE, "==> LPSV ... ");
149           err = ftp_lpsv (csock, addr, port);
150         }
151       break;
152     default:
153       abort ();
154     }
155
156   return err;
157 }
158
159 /*
160  * This function sets up an active data connection with the FTP server.
161  * It is merely a wrapper around ftp_eprt, ftp_lprt and ftp_port.
162  */
163 static uerr_t
164 ftp_do_port (int csock, int *local_sock)
165 {
166   uerr_t err;
167   ip_address cip;
168
169   if (!socket_ip_address (csock, &cip, ENDPOINT_PEER))
170     abort ();
171
172   /* If our control connection is over IPv6, then we first try EPRT and then
173    * LPRT if the former is not supported. If the control connection is over
174    * IPv4, we simply issue the good old PORT request. */
175   switch (cip.family)
176     {
177     case AF_INET:
178       if (!opt.server_response)
179         logputs (LOG_VERBOSE, "==> PORT ... ");
180       err = ftp_port (csock, local_sock);
181       break;
182     case AF_INET6:
183       if (!opt.server_response)
184         logputs (LOG_VERBOSE, "==> EPRT ... ");
185       err = ftp_eprt (csock, local_sock);
186
187       /* If EPRT is not supported try LPRT */
188       if (err == FTPPORTERR)
189         {
190           if (!opt.server_response)
191             logputs (LOG_VERBOSE, "==> LPRT ... ");
192           err = ftp_lprt (csock, local_sock);
193         }
194       break;
195     default:
196       abort ();
197     }
198   return err;
199 }
200 #else
201
202 static uerr_t
203 ftp_do_pasv (int csock, ip_address *addr, int *port)
204 {
205   if (!opt.server_response)
206     logputs (LOG_VERBOSE, "==> PASV ... ");
207   return ftp_pasv (csock, addr, port);
208 }
209
210 static uerr_t
211 ftp_do_port (int csock, int *local_sock)
212 {
213   if (!opt.server_response)
214     logputs (LOG_VERBOSE, "==> PORT ... ");
215   return ftp_port (csock, local_sock);
216 }
217 #endif
218
219 static void
220 print_length (wgint size, wgint start, bool authoritative)
221 {
222   logprintf (LOG_VERBOSE, _("Length: %s"), number_to_static_string (size));
223   if (size >= 1024)
224     logprintf (LOG_VERBOSE, " (%s)", human_readable (size));
225   if (start > 0)
226     {
227       if (size - start >= 1024)
228         logprintf (LOG_VERBOSE, _(", %s (%s) remaining"),
229                    number_to_static_string (size - start),
230                    human_readable (size - start));
231       else
232         logprintf (LOG_VERBOSE, _(", %s remaining"),
233                    number_to_static_string (size - start));
234     }
235   logputs (LOG_VERBOSE, !authoritative ? _(" (unauthoritative)\n") : "\n");
236 }
237
238 static uerr_t ftp_get_listing (struct url *, ccon *, struct fileinfo **);
239
240 /* Retrieves a file with denoted parameters through opening an FTP
241    connection to the server.  It always closes the data connection,
242    and closes the control connection in case of error.  If warc_tmp
243    is non-NULL, the downloaded data will be written there as well.  */
244 static uerr_t
245 getftp (struct url *u, wgint passed_expected_bytes, wgint *qtyread,
246         wgint restval, ccon *con, int count, FILE *warc_tmp)
247 {
248   int csock, dtsock, local_sock, res;
249   uerr_t err = RETROK;          /* appease the compiler */
250   FILE *fp;
251   char *respline, *tms;
252   const char *user, *passwd, *tmrate;
253   int cmd = con->cmd;
254   bool pasv_mode_open = false;
255   wgint expected_bytes = 0;
256   bool got_expected_bytes = false;
257   bool rest_failed = false;
258   int flags;
259   wgint rd_size, previous_rd_size = 0;
260   char type_char;
261   bool try_again;
262   bool list_a_used = false;
263
264   assert (con != NULL);
265   assert (con->target != NULL);
266
267   /* Debug-check of the sanity of the request by making sure that LIST
268      and RETR are never both requested (since we can handle only one
269      at a time.  */
270   assert (!((cmd & DO_LIST) && (cmd & DO_RETR)));
271   /* Make sure that at least *something* is requested.  */
272   assert ((cmd & (DO_LIST | DO_CWD | DO_RETR | DO_LOGIN)) != 0);
273
274   *qtyread = restval;
275
276   user = u->user;
277   passwd = u->passwd;
278   search_netrc (u->host, (const char **)&user, (const char **)&passwd, 1);
279   user = user ? user : (opt.ftp_user ? opt.ftp_user : opt.user);
280   if (!user) user = "anonymous";
281   passwd = passwd ? passwd : (opt.ftp_passwd ? opt.ftp_passwd : opt.passwd);
282   if (!passwd) passwd = "-wget@";
283
284   dtsock = -1;
285   local_sock = -1;
286   con->dltime = 0;
287
288   if (!(cmd & DO_LOGIN))
289     csock = con->csock;
290   else                          /* cmd & DO_LOGIN */
291     {
292       char    *host = con->proxy ? con->proxy->host : u->host;
293       int      port = con->proxy ? con->proxy->port : u->port;
294
295       /* Login to the server: */
296
297       /* First: Establish the control connection.  */
298
299       csock = connect_to_host (host, port);
300       if (csock == E_HOST)
301           return HOSTERR;
302       else if (csock < 0)
303           return (retryable_socket_connect_error (errno)
304                   ? CONERROR : CONIMPOSSIBLE);
305
306       if (cmd & LEAVE_PENDING)
307         con->csock = csock;
308       else
309         con->csock = -1;
310
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       if (con->proxy)
317         {
318           /* If proxy is in use, log in as username@target-site. */
319           char *logname = concat_strings (user, "@", u->host, (char *) 0);
320           err = ftp_login (csock, logname, passwd);
321           xfree (logname);
322         }
323       else
324         err = ftp_login (csock, user, passwd);
325
326       /* FTPRERR, FTPSRVERR, WRITEFAILED, FTPLOGREFUSED, FTPLOGINC */
327       switch (err)
328         {
329         case FTPRERR:
330           logputs (LOG_VERBOSE, "\n");
331           logputs (LOG_NOTQUIET, _("\
332 Error in server response, closing control connection.\n"));
333           fd_close (csock);
334           con->csock = -1;
335           return err;
336         case FTPSRVERR:
337           logputs (LOG_VERBOSE, "\n");
338           logputs (LOG_NOTQUIET, _("Error in server greeting.\n"));
339           fd_close (csock);
340           con->csock = -1;
341           return err;
342         case WRITEFAILED:
343           logputs (LOG_VERBOSE, "\n");
344           logputs (LOG_NOTQUIET,
345                    _("Write failed, closing control connection.\n"));
346           fd_close (csock);
347           con->csock = -1;
348           return err;
349         case FTPLOGREFUSED:
350           logputs (LOG_VERBOSE, "\n");
351           logputs (LOG_NOTQUIET, _("The server refuses login.\n"));
352           fd_close (csock);
353           con->csock = -1;
354           return FTPLOGREFUSED;
355         case FTPLOGINC:
356           logputs (LOG_VERBOSE, "\n");
357           logputs (LOG_NOTQUIET, _("Login incorrect.\n"));
358           fd_close (csock);
359           con->csock = -1;
360           return FTPLOGINC;
361         case FTPOK:
362           if (!opt.server_response)
363             logputs (LOG_VERBOSE, _("Logged in!\n"));
364           break;
365         default:
366           abort ();
367         }
368       /* Third: Get the system type */
369       if (!opt.server_response)
370         logprintf (LOG_VERBOSE, "==> SYST ... ");
371       err = ftp_syst (csock, &con->rs, &con->rsu);
372       /* FTPRERR */
373       switch (err)
374         {
375         case FTPRERR:
376           logputs (LOG_VERBOSE, "\n");
377           logputs (LOG_NOTQUIET, _("\
378 Error in server response, closing control connection.\n"));
379           fd_close (csock);
380           con->csock = -1;
381           return err;
382         case FTPSRVERR:
383           logputs (LOG_VERBOSE, "\n");
384           logputs (LOG_NOTQUIET,
385                    _("Server error, can't determine system type.\n"));
386           break;
387         case FTPOK:
388           /* Everything is OK.  */
389           break;
390         default:
391           abort ();
392         }
393       if (!opt.server_response && err != FTPSRVERR)
394         logputs (LOG_VERBOSE, _("done.    "));
395
396       /* 2013-10-17 Andrea Urbani (matfanjol)
397          According to the system type I choose which
398          list command will be used.
399          If I don't know that system, I will try, the
400          first time of each session, "LIST -a" and
401          "LIST". (see __LIST_A_EXPLANATION__ below) */
402       switch (con->rs)
403         {
404         case ST_VMS:
405           /* About ST_VMS there is an old note:
406              2008-01-29  SMS.  For a VMS FTP server, where "LIST -a" may not
407              fail, but will never do what is desired here,
408              skip directly to the simple "LIST" command
409              (assumed to be the last one in the list).  */
410           DEBUGP (("\nVMS: I know it and I will use \"LIST\" as standard list command\n"));
411           con->st |= LIST_AFTER_LIST_A_CHECK_DONE;
412           con->st |= AVOID_LIST_A;
413           break;
414         case ST_UNIX:
415           if (con->rsu == UST_MULTINET)
416             {
417               DEBUGP (("\nUNIX MultiNet: I know it and I will use \"LIST\" "
418                        "as standard list command\n"));
419               con->st |= LIST_AFTER_LIST_A_CHECK_DONE;
420               con->st |= AVOID_LIST_A;
421             }
422           else if (con->rsu == UST_TYPE_L8)
423             {
424               DEBUGP (("\nUNIX TYPE L8: I know it and I will use \"LIST -a\" "
425                        "as standard list command\n"));
426               con->st |= LIST_AFTER_LIST_A_CHECK_DONE;
427               con->st |= AVOID_LIST;
428             }
429           break;
430         default:
431           break;
432         }
433
434       /* Fourth: Find the initial ftp directory */
435
436       if (!opt.server_response)
437         logprintf (LOG_VERBOSE, "==> PWD ... ");
438       err = ftp_pwd (csock, &con->id);
439       /* FTPRERR */
440       switch (err)
441         {
442         case FTPRERR:
443           logputs (LOG_VERBOSE, "\n");
444           logputs (LOG_NOTQUIET, _("\
445 Error in server response, closing control connection.\n"));
446           fd_close (csock);
447           con->csock = -1;
448           return err;
449         case FTPSRVERR :
450           /* PWD unsupported -- assume "/". */
451           xfree_null (con->id);
452           con->id = xstrdup ("/");
453           break;
454         case FTPOK:
455           /* Everything is OK.  */
456           break;
457         default:
458           abort ();
459         }
460
461 #if 0
462       /* 2004-09-17 SMS.
463          Don't help me out.  Please.
464          A reasonably recent VMS FTP server will cope just fine with
465          UNIX file specifications.  This code just spoils things.
466          Discarding the device name, for example, is not a wise move.
467          This code was disabled but left in as an example of what not
468          to do.
469       */
470
471       /* VMS will report something like "PUB$DEVICE:[INITIAL.FOLDER]".
472          Convert it to "/INITIAL/FOLDER" */
473       if (con->rs == ST_VMS)
474         {
475           char *path = strchr (con->id, '[');
476           char *pathend = path ? strchr (path + 1, ']') : NULL;
477           if (!path || !pathend)
478             DEBUGP (("Initial VMS directory not in the form [...]!\n"));
479           else
480             {
481               char *idir = con->id;
482               DEBUGP (("Preprocessing the initial VMS directory\n"));
483               DEBUGP (("  old = '%s'\n", con->id));
484               /* We do the conversion in-place by copying the stuff
485                  between [ and ] to the beginning, and changing dots
486                  to slashes at the same time.  */
487               *idir++ = '/';
488               for (++path; path < pathend; path++, idir++)
489                 *idir = *path == '.' ? '/' : *path;
490               *idir = '\0';
491               DEBUGP (("  new = '%s'\n\n", con->id));
492             }
493         }
494 #endif /* 0 */
495
496       if (!opt.server_response)
497         logputs (LOG_VERBOSE, _("done.\n"));
498
499       /* Fifth: Set the FTP type.  */
500       type_char = ftp_process_type (u->params);
501       if (!opt.server_response)
502         logprintf (LOG_VERBOSE, "==> TYPE %c ... ", type_char);
503       err = ftp_type (csock, type_char);
504       /* FTPRERR, WRITEFAILED, FTPUNKNOWNTYPE */
505       switch (err)
506         {
507         case FTPRERR:
508           logputs (LOG_VERBOSE, "\n");
509           logputs (LOG_NOTQUIET, _("\
510 Error in server response, closing control connection.\n"));
511           fd_close (csock);
512           con->csock = -1;
513           return err;
514         case WRITEFAILED:
515           logputs (LOG_VERBOSE, "\n");
516           logputs (LOG_NOTQUIET,
517                    _("Write failed, closing control connection.\n"));
518           fd_close (csock);
519           con->csock = -1;
520           return err;
521         case FTPUNKNOWNTYPE:
522           logputs (LOG_VERBOSE, "\n");
523           logprintf (LOG_NOTQUIET,
524                      _("Unknown type `%c', closing control connection.\n"),
525                      type_char);
526           fd_close (csock);
527           con->csock = -1;
528           return err;
529         case FTPOK:
530           /* Everything is OK.  */
531           break;
532         default:
533           abort ();
534         }
535       if (!opt.server_response)
536         logputs (LOG_VERBOSE, _("done.  "));
537     } /* do login */
538
539   if (cmd & DO_CWD)
540     {
541       if (!*u->dir)
542         logputs (LOG_VERBOSE, _("==> CWD not needed.\n"));
543       else
544         {
545           const char *targ = NULL;
546           int cwd_count;
547           int cwd_end;
548           int cwd_start;
549
550           char *target = u->dir;
551
552           DEBUGP (("changing working directory\n"));
553
554           /* Change working directory.  To change to a non-absolute
555              Unix directory, we need to prepend initial directory
556              (con->id) to it.  Absolute directories "just work".
557
558              A relative directory is one that does not begin with '/'
559              and, on non-Unix OS'es, one that doesn't begin with
560              "[a-z]:".
561
562              This is not done for OS400, which doesn't use
563              "/"-delimited directories, nor does it support directory
564              hierarchies.  "CWD foo" followed by "CWD bar" leaves us
565              in "bar", not in "foo/bar", as would be customary
566              elsewhere.  */
567
568             /* 2004-09-20 SMS.
569                Why is this wise even on UNIX?  It certainly fouls VMS.
570                See below for a more reliable, more universal method.
571             */
572
573             /* 2008-04-22 MJC.
574                I'm not crazy about it either. I'm informed it's useful
575                for misconfigured servers that have some dirs in the path
576                with +x but -r, but this method is not RFC-conformant. I
577                understand the need to deal with crappy server
578                configurations, but it's far better to use the canonical
579                method first, and fall back to kludges second.
580             */
581
582           if (target[0] != '/'
583               && !(con->rs != ST_UNIX
584                    && c_isalpha (target[0])
585                    && target[1] == ':')
586               && (con->rs != ST_OS400)
587               && (con->rs != ST_VMS))
588             {
589               int idlen = strlen (con->id);
590               char *ntarget, *p;
591
592               /* Strip trailing slash(es) from con->id. */
593               while (idlen > 0 && con->id[idlen - 1] == '/')
594                 --idlen;
595               p = ntarget = (char *)alloca (idlen + 1 + strlen (u->dir) + 1);
596               memcpy (p, con->id, idlen);
597               p += idlen;
598               *p++ = '/';
599               strcpy (p, target);
600
601               DEBUGP (("Prepended initial PWD to relative path:\n"));
602               DEBUGP (("   pwd: '%s'\n   old: '%s'\n  new: '%s'\n",
603                        con->id, target, ntarget));
604               target = ntarget;
605             }
606
607 #if 0
608           /* 2004-09-17 SMS.
609              Don't help me out.  Please.
610              A reasonably recent VMS FTP server will cope just fine with
611              UNIX file specifications.  This code just spoils things.
612              Discarding the device name, for example, is not a wise
613              move.
614              This code was disabled but left in as an example of what
615              not to do.
616           */
617
618           /* If the FTP host runs VMS, we will have to convert the absolute
619              directory path in UNIX notation to absolute directory path in
620              VMS notation as VMS FTP servers do not like UNIX notation of
621              absolute paths.  "VMS notation" is [dir.subdir.subsubdir]. */
622
623           if (con->rs == ST_VMS)
624             {
625               char *tmpp;
626               char *ntarget = (char *)alloca (strlen (target) + 2);
627               /* We use a converted initial dir, so directories in
628                  TARGET will be separated with slashes, something like
629                  "/INITIAL/FOLDER/DIR/SUBDIR".  Convert that to
630                  "[INITIAL.FOLDER.DIR.SUBDIR]".  */
631               strcpy (ntarget, target);
632               assert (*ntarget == '/');
633               *ntarget = '[';
634               for (tmpp = ntarget + 1; *tmpp; tmpp++)
635                 if (*tmpp == '/')
636                   *tmpp = '.';
637               *tmpp++ = ']';
638               *tmpp = '\0';
639               DEBUGP (("Changed file name to VMS syntax:\n"));
640               DEBUGP (("  Unix: '%s'\n  VMS: '%s'\n", target, ntarget));
641               target = ntarget;
642             }
643 #endif /* 0 */
644
645           /* 2004-09-20 SMS.
646              A relative directory is relative to the initial directory.
647              Thus, what _is_ useful on VMS (and probably elsewhere) is
648              to CWD to the initial directory (ideally, whatever the
649              server reports, _exactly_, NOT badly UNIX-ixed), and then
650              CWD to the (new) relative directory.  This should probably
651              be restructured as a function, called once or twice, but
652              I'm lazy enough to take the badly indented loop short-cut
653              for now.
654           */
655
656           /* Decide on one pass (absolute) or two (relative).
657              The VMS restriction may be relaxed when the squirrely code
658              above is reformed.
659           */
660           if ((con->rs == ST_VMS) && (target[0] != '/'))
661             {
662               cwd_start = 0;
663               DEBUGP (("Using two-step CWD for relative path.\n"));
664             }
665           else
666             {
667               /* Go straight to the target. */
668               cwd_start = 1;
669             }
670
671           /* At least one VMS FTP server (TCPware V5.6-2) can switch to
672              a UNIX emulation mode when given a UNIX-like directory
673              specification (like "a/b/c").  If allowed to continue this
674              way, LIST interpretation will be confused, because the
675              system type (SYST response) will not be re-checked, and
676              future UNIX-format directory listings (for multiple URLs or
677              "-r") will be horribly misinterpreted.
678
679              The cheap and nasty work-around is to do a "CWD []" after a
680              UNIX-like directory specification is used.  (A single-level
681              directory is harmless.)  This puts the TCPware server back
682              into VMS mode, and does no harm on other servers.
683
684              Unlike the rest of this block, this particular behavior
685              _is_ VMS-specific, so it gets its own VMS test.
686           */
687           if ((con->rs == ST_VMS) && (strchr( target, '/') != NULL))
688             {
689               cwd_end = 3;
690               DEBUGP (("Using extra \"CWD []\" step for VMS server.\n"));
691             }
692           else
693             {
694               cwd_end = 2;
695             }
696
697           /* 2004-09-20 SMS. */
698           /* Sorry about the deviant indenting.  Laziness. */
699
700           for (cwd_count = cwd_start; cwd_count < cwd_end; cwd_count++)
701             {
702           switch (cwd_count)
703             {
704               case 0:
705                 /* Step one (optional): Go to the initial directory,
706                    exactly as reported by the server.
707                 */
708                 targ = con->id;
709                 break;
710
711               case 1:
712                 /* Step two: Go to the target directory.  (Absolute or
713                    relative will work now.)
714                 */
715                 targ = target;
716                 break;
717
718               case 2:
719                 /* Step three (optional): "CWD []" to restore server
720                    VMS-ness.
721                 */
722                 targ = "[]";
723                 break;
724
725               default:
726                 /* Can't happen. */
727                 assert (1);
728             }
729
730           if (!opt.server_response)
731             logprintf (LOG_VERBOSE, "==> CWD (%d) %s ... ", cwd_count,
732                        quotearg_style (escape_quoting_style, target));
733           err = ftp_cwd (csock, targ);
734           /* FTPRERR, WRITEFAILED, FTPNSFOD */
735           switch (err)
736             {
737             case FTPRERR:
738               logputs (LOG_VERBOSE, "\n");
739               logputs (LOG_NOTQUIET, _("\
740 Error in server response, closing control connection.\n"));
741               fd_close (csock);
742               con->csock = -1;
743               return err;
744             case WRITEFAILED:
745               logputs (LOG_VERBOSE, "\n");
746               logputs (LOG_NOTQUIET,
747                        _("Write failed, closing control connection.\n"));
748               fd_close (csock);
749               con->csock = -1;
750               return err;
751             case FTPNSFOD:
752               logputs (LOG_VERBOSE, "\n");
753               logprintf (LOG_NOTQUIET, _("No such directory %s.\n\n"),
754                          quote (u->dir));
755               fd_close (csock);
756               con->csock = -1;
757               return err;
758             case FTPOK:
759               break;
760             default:
761               abort ();
762             }
763           if (!opt.server_response)
764             logputs (LOG_VERBOSE, _("done.\n"));
765
766         } /* for */
767
768           /* 2004-09-20 SMS. */
769           /* End of deviant indenting. */
770
771         } /* else */
772     }
773   else /* do not CWD */
774     logputs (LOG_VERBOSE, _("==> CWD not required.\n"));
775
776   if ((cmd & DO_RETR) && passed_expected_bytes == 0)
777     {
778       if (opt.verbose)
779         {
780           if (!opt.server_response)
781             logprintf (LOG_VERBOSE, "==> SIZE %s ... ",
782                        quotearg_style (escape_quoting_style, u->file));
783         }
784
785       err = ftp_size (csock, u->file, &expected_bytes);
786       /* FTPRERR */
787       switch (err)
788         {
789         case FTPRERR:
790         case FTPSRVERR:
791           logputs (LOG_VERBOSE, "\n");
792           logputs (LOG_NOTQUIET, _("\
793 Error in server response, closing control connection.\n"));
794           fd_close (csock);
795           con->csock = -1;
796           return err;
797         case FTPOK:
798           got_expected_bytes = true;
799           /* Everything is OK.  */
800           break;
801         default:
802           abort ();
803         }
804         if (!opt.server_response)
805           logprintf (LOG_VERBOSE, expected_bytes ? "%s\n" : _("done.\n"),
806                      number_to_static_string (expected_bytes));
807     }
808
809   if (cmd & DO_RETR && restval > 0 && restval == expected_bytes)
810     {
811       /* Server confirms that file has length restval. We should stop now.
812          Some servers (f.e. NcFTPd) return error when receive REST 0 */
813       logputs (LOG_VERBOSE, _("File has already been retrieved.\n"));
814       fd_close (csock);
815       con->csock = -1;
816       return RETRFINISHED;
817     }
818
819   do
820   {
821   try_again = false;
822   /* If anything is to be retrieved, PORT (or PASV) must be sent.  */
823   if (cmd & (DO_LIST | DO_RETR))
824     {
825       if (opt.ftp_pasv)
826         {
827           ip_address passive_addr;
828           int        passive_port;
829           err = ftp_do_pasv (csock, &passive_addr, &passive_port);
830           /* FTPRERR, WRITEFAILED, FTPNOPASV, FTPINVPASV */
831           switch (err)
832             {
833             case FTPRERR:
834               logputs (LOG_VERBOSE, "\n");
835               logputs (LOG_NOTQUIET, _("\
836 Error in server response, closing control connection.\n"));
837               fd_close (csock);
838               con->csock = -1;
839               return err;
840             case WRITEFAILED:
841               logputs (LOG_VERBOSE, "\n");
842               logputs (LOG_NOTQUIET,
843                        _("Write failed, closing control connection.\n"));
844               fd_close (csock);
845               con->csock = -1;
846               return err;
847             case FTPNOPASV:
848               logputs (LOG_VERBOSE, "\n");
849               logputs (LOG_NOTQUIET, _("Cannot initiate PASV transfer.\n"));
850               break;
851             case FTPINVPASV:
852               logputs (LOG_VERBOSE, "\n");
853               logputs (LOG_NOTQUIET, _("Cannot parse PASV response.\n"));
854               break;
855             case FTPOK:
856               break;
857             default:
858               abort ();
859             }   /* switch (err) */
860           if (err==FTPOK)
861             {
862               DEBUGP (("trying to connect to %s port %d\n",
863                       print_address (&passive_addr), passive_port));
864               dtsock = connect_to_ip (&passive_addr, passive_port, NULL);
865               if (dtsock < 0)
866                 {
867                   int save_errno = errno;
868                   fd_close (csock);
869                   con->csock = -1;
870                   logprintf (LOG_VERBOSE, _("couldn't connect to %s port %d: %s\n"),
871                              print_address (&passive_addr), passive_port,
872                              strerror (save_errno));
873                   return (retryable_socket_connect_error (save_errno)
874                           ? CONERROR : CONIMPOSSIBLE);
875                 }
876
877               pasv_mode_open = true;  /* Flag to avoid accept port */
878               if (!opt.server_response)
879                 logputs (LOG_VERBOSE, _("done.    "));
880             } /* err==FTP_OK */
881         }
882
883       if (!pasv_mode_open)   /* Try to use a port command if PASV failed */
884         {
885           err = ftp_do_port (csock, &local_sock);
886           /* FTPRERR, WRITEFAILED, bindport (FTPSYSERR), HOSTERR,
887              FTPPORTERR */
888           switch (err)
889             {
890             case FTPRERR:
891               logputs (LOG_VERBOSE, "\n");
892               logputs (LOG_NOTQUIET, _("\
893 Error in server response, closing control connection.\n"));
894               fd_close (csock);
895               con->csock = -1;
896               fd_close (dtsock);
897               fd_close (local_sock);
898               return err;
899             case WRITEFAILED:
900               logputs (LOG_VERBOSE, "\n");
901               logputs (LOG_NOTQUIET,
902                        _("Write failed, closing control connection.\n"));
903               fd_close (csock);
904               con->csock = -1;
905               fd_close (dtsock);
906               fd_close (local_sock);
907               return err;
908             case CONSOCKERR:
909               logputs (LOG_VERBOSE, "\n");
910               logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
911               fd_close (csock);
912               con->csock = -1;
913               fd_close (dtsock);
914               fd_close (local_sock);
915               return err;
916             case FTPSYSERR:
917               logputs (LOG_VERBOSE, "\n");
918               logprintf (LOG_NOTQUIET, _("Bind error (%s).\n"),
919                          strerror (errno));
920               fd_close (dtsock);
921               return err;
922             case FTPPORTERR:
923               logputs (LOG_VERBOSE, "\n");
924               logputs (LOG_NOTQUIET, _("Invalid PORT.\n"));
925               fd_close (csock);
926               con->csock = -1;
927               fd_close (dtsock);
928               fd_close (local_sock);
929               return err;
930             case FTPOK:
931               break;
932             default:
933               abort ();
934             } /* port switch */
935           if (!opt.server_response)
936             logputs (LOG_VERBOSE, _("done.    "));
937         } /* dtsock == -1 */
938     } /* cmd & (DO_LIST | DO_RETR) */
939
940   /* Restart if needed.  */
941   if (restval && (cmd & DO_RETR))
942     {
943       if (!opt.server_response)
944         logprintf (LOG_VERBOSE, "==> REST %s ... ",
945                    number_to_static_string (restval));
946       err = ftp_rest (csock, restval);
947
948       /* FTPRERR, WRITEFAILED, FTPRESTFAIL */
949       switch (err)
950         {
951         case FTPRERR:
952           logputs (LOG_VERBOSE, "\n");
953           logputs (LOG_NOTQUIET, _("\
954 Error in server response, closing control connection.\n"));
955           fd_close (csock);
956           con->csock = -1;
957           fd_close (dtsock);
958           fd_close (local_sock);
959           return err;
960         case WRITEFAILED:
961           logputs (LOG_VERBOSE, "\n");
962           logputs (LOG_NOTQUIET,
963                    _("Write failed, closing control connection.\n"));
964           fd_close (csock);
965           con->csock = -1;
966           fd_close (dtsock);
967           fd_close (local_sock);
968           return err;
969         case FTPRESTFAIL:
970           logputs (LOG_VERBOSE, _("\nREST failed, starting from scratch.\n"));
971           rest_failed = true;
972           break;
973         case FTPOK:
974           break;
975         default:
976           abort ();
977         }
978       if (err != FTPRESTFAIL && !opt.server_response)
979         logputs (LOG_VERBOSE, _("done.    "));
980     } /* restval && cmd & DO_RETR */
981
982   if (cmd & DO_RETR)
983     {
984       /* If we're in spider mode, don't really retrieve anything except
985          the directory listing and verify whether the given "file" exists.  */
986       if (opt.spider)
987         {
988           bool exists = false;
989           uerr_t res;
990           struct fileinfo *f;
991           res = ftp_get_listing (u, con, &f);
992           /* Set the DO_RETR command flag again, because it gets unset when
993              calling ftp_get_listing() and would otherwise cause an assertion
994              failure earlier on when this function gets repeatedly called
995              (e.g., when recursing).  */
996           con->cmd |= DO_RETR;
997           if (res == RETROK)
998             {
999               while (f)
1000                 {
1001                   if (!strcmp (f->name, u->file))
1002                     {
1003                       exists = true;
1004                       break;
1005                     }
1006                   f = f->next;
1007                 }
1008               if (exists)
1009                 {
1010                   logputs (LOG_VERBOSE, "\n");
1011                   logprintf (LOG_NOTQUIET, _("File %s exists.\n"),
1012                              quote (u->file));
1013                 }
1014               else
1015                 {
1016                   logputs (LOG_VERBOSE, "\n");
1017                   logprintf (LOG_NOTQUIET, _("No such file %s.\n"),
1018                              quote (u->file));
1019                 }
1020             }
1021           fd_close (csock);
1022           con->csock = -1;
1023           fd_close (dtsock);
1024           fd_close (local_sock);
1025           return RETRFINISHED;
1026         }
1027
1028       if (opt.verbose)
1029         {
1030           if (!opt.server_response)
1031             {
1032               if (restval)
1033                 logputs (LOG_VERBOSE, "\n");
1034               logprintf (LOG_VERBOSE, "==> RETR %s ... ",
1035                          quotearg_style (escape_quoting_style, u->file));
1036             }
1037         }
1038
1039       err = ftp_retr (csock, u->file);
1040       /* FTPRERR, WRITEFAILED, FTPNSFOD */
1041       switch (err)
1042         {
1043         case FTPRERR:
1044           logputs (LOG_VERBOSE, "\n");
1045           logputs (LOG_NOTQUIET, _("\
1046 Error in server response, closing control connection.\n"));
1047           fd_close (csock);
1048           con->csock = -1;
1049           fd_close (dtsock);
1050           fd_close (local_sock);
1051           return err;
1052         case WRITEFAILED:
1053           logputs (LOG_VERBOSE, "\n");
1054           logputs (LOG_NOTQUIET,
1055                    _("Write failed, closing control connection.\n"));
1056           fd_close (csock);
1057           con->csock = -1;
1058           fd_close (dtsock);
1059           fd_close (local_sock);
1060           return err;
1061         case FTPNSFOD:
1062           logputs (LOG_VERBOSE, "\n");
1063           logprintf (LOG_NOTQUIET, _("No such file %s.\n\n"),
1064                      quote (u->file));
1065           fd_close (dtsock);
1066           fd_close (local_sock);
1067           return err;
1068         case FTPOK:
1069           break;
1070         default:
1071           abort ();
1072         }
1073
1074       if (!opt.server_response)
1075         logputs (LOG_VERBOSE, _("done.\n"));
1076
1077       if (! got_expected_bytes)
1078         expected_bytes = ftp_expected_bytes (ftp_last_respline);
1079     } /* do retrieve */
1080
1081   if (cmd & DO_LIST)
1082     {
1083       if (!opt.server_response)
1084         logputs (LOG_VERBOSE, "==> LIST ... ");
1085       /* As Maciej W. Rozycki (macro@ds2.pg.gda.pl) says, `LIST'
1086          without arguments is better than `LIST .'; confirmed by
1087          RFC959.  */
1088       err = ftp_list (csock, NULL, con->st&AVOID_LIST_A, con->st&AVOID_LIST, &list_a_used);
1089
1090       /* FTPRERR, WRITEFAILED */
1091       switch (err)
1092         {
1093         case FTPRERR:
1094           logputs (LOG_VERBOSE, "\n");
1095           logputs (LOG_NOTQUIET, _("\
1096 Error in server response, closing control connection.\n"));
1097           fd_close (csock);
1098           con->csock = -1;
1099           fd_close (dtsock);
1100           fd_close (local_sock);
1101           return err;
1102         case WRITEFAILED:
1103           logputs (LOG_VERBOSE, "\n");
1104           logputs (LOG_NOTQUIET,
1105                    _("Write failed, closing control connection.\n"));
1106           fd_close (csock);
1107           con->csock = -1;
1108           fd_close (dtsock);
1109           fd_close (local_sock);
1110           return err;
1111         case FTPNSFOD:
1112           logputs (LOG_VERBOSE, "\n");
1113           logprintf (LOG_NOTQUIET, _("No such file or directory %s.\n\n"),
1114                      quote ("."));
1115           fd_close (dtsock);
1116           fd_close (local_sock);
1117           return err;
1118         case FTPOK:
1119           break;
1120         default:
1121           abort ();
1122         }
1123       if (!opt.server_response)
1124         logputs (LOG_VERBOSE, _("done.\n"));
1125
1126       if (! got_expected_bytes)
1127         expected_bytes = ftp_expected_bytes (ftp_last_respline);
1128     } /* cmd & DO_LIST */
1129
1130   if (!(cmd & (DO_LIST | DO_RETR)) || (opt.spider && !(cmd & DO_LIST)))
1131     return RETRFINISHED;
1132
1133   /* Some FTP servers return the total length of file after REST
1134      command, others just return the remaining size. */
1135   if (passed_expected_bytes && restval && expected_bytes
1136       && (expected_bytes == passed_expected_bytes - restval))
1137     {
1138       DEBUGP (("Lying FTP server found, adjusting.\n"));
1139       expected_bytes = passed_expected_bytes;
1140     }
1141
1142   /* If no transmission was required, then everything is OK.  */
1143   if (!pasv_mode_open)  /* we are not using pasive mode so we need
1144                               to accept */
1145     {
1146       /* Wait for the server to connect to the address we're waiting
1147          at.  */
1148       dtsock = accept_connection (local_sock);
1149       if (dtsock < 0)
1150         {
1151           logprintf (LOG_NOTQUIET, "accept: %s\n", strerror (errno));
1152           return CONERROR;
1153         }
1154     }
1155
1156   /* Open the file -- if output_stream is set, use it instead.  */
1157
1158   /* 2005-04-17 SMS.
1159      Note that having the output_stream ("-O") file opened in main()
1160      (main.c) rather limits the ability in VMS to open the file
1161      differently for ASCII versus binary FTP here.  (Of course, doing it
1162      there allows a open failure to be detected immediately, without first
1163      connecting to the server.)
1164   */
1165   if (!output_stream || con->cmd & DO_LIST)
1166     {
1167 /* On VMS, alter the name as required. */
1168 #ifdef __VMS
1169       char *targ;
1170
1171       targ = ods_conform (con->target);
1172       if (targ != con->target)
1173         {
1174           xfree (con->target);
1175           con->target = targ;
1176         }
1177 #endif /* def __VMS */
1178
1179       mkalldirs (con->target);
1180       if (opt.backups)
1181         rotate_backups (con->target);
1182
1183 /* 2005-04-15 SMS.
1184    For VMS, define common fopen() optional arguments, and a handy macro
1185    for use as a variable "binary" flag.
1186    Elsewhere, define a constant "binary" flag.
1187    Isn't it nice to have distinct text and binary file types?
1188 */
1189 /* 2011-09-30 SMS.
1190    Added listing files to the set of non-"binary" (text, Stream_LF)
1191    files.  (Wget works either way, but other programs, like, say, text
1192    editors, work better on listing files which have text attributes.)
1193    Now we use "binary" attributes for a binary ("IMAGE") transfer,
1194    unless "--ftp-stmlf" was specified, and we always use non-"binary"
1195    (text, Stream_LF) attributes for a listing file, or for an ASCII
1196    transfer.
1197    Tidied the VMS-specific BIN_TYPE_xxx macros, and changed the call to
1198    fopen_excl() (restored?) to use BIN_TYPE_FILE instead of "true".
1199 */
1200 #ifdef __VMS
1201 # define BIN_TYPE_TRANSFER (type_char != 'A')
1202 # define BIN_TYPE_FILE \
1203    ((!(cmd & DO_LIST)) && BIN_TYPE_TRANSFER && (opt.ftp_stmlf == 0))
1204 # define FOPEN_OPT_ARGS "fop=sqo", "acc", acc_cb, &open_id
1205 # define FOPEN_OPT_ARGS_BIN "ctx=bin,stm", "rfm=fix", "mrs=512" FOPEN_OPT_ARGS
1206 #else /* def __VMS */
1207 # define BIN_TYPE_FILE true
1208 #endif /* def __VMS [else] */
1209
1210       if (restval && !(con->cmd & DO_LIST))
1211         {
1212 #ifdef __VMS
1213           int open_id;
1214
1215           if (BIN_TYPE_FILE)
1216             {
1217               open_id = 3;
1218               fp = fopen (con->target, "ab", FOPEN_OPT_ARGS_BIN);
1219             }
1220           else
1221             {
1222               open_id = 4;
1223               fp = fopen (con->target, "a", FOPEN_OPT_ARGS);
1224             }
1225 #else /* def __VMS */
1226           fp = fopen (con->target, "ab");
1227 #endif /* def __VMS [else] */
1228         }
1229       else if (opt.noclobber || opt.always_rest || opt.timestamping || opt.dirstruct
1230                || opt.output_document || count > 0)
1231         {
1232           if (opt.unlink && file_exists_p (con->target))
1233             {
1234               int res = unlink (con->target);
1235               if (res < 0)
1236                 {
1237                   logprintf (LOG_NOTQUIET, "%s: %s\n", con->target,
1238                     strerror (errno));
1239                     fd_close (csock);
1240                     con->csock = -1;
1241                     fd_close (dtsock);
1242                     fd_close (local_sock);
1243                     return UNLINKERR;
1244                 }
1245             }
1246
1247 #ifdef __VMS
1248           int open_id;
1249
1250           if (BIN_TYPE_FILE)
1251             {
1252               open_id = 5;
1253               fp = fopen (con->target, "wb", FOPEN_OPT_ARGS_BIN);
1254             }
1255           else
1256             {
1257               open_id = 6;
1258               fp = fopen (con->target, "w", FOPEN_OPT_ARGS);
1259             }
1260 #else /* def __VMS */
1261           fp = fopen (con->target, "wb");
1262 #endif /* def __VMS [else] */
1263         }
1264       else
1265         {
1266           fp = fopen_excl (con->target, BIN_TYPE_FILE);
1267           if (!fp && errno == EEXIST)
1268             {
1269               /* We cannot just invent a new name and use it (which is
1270                  what functions like unique_create typically do)
1271                  because we told the user we'd use this name.
1272                  Instead, return and retry the download.  */
1273               logprintf (LOG_NOTQUIET, _("%s has sprung into existence.\n"),
1274                          con->target);
1275               fd_close (csock);
1276               con->csock = -1;
1277               fd_close (dtsock);
1278               fd_close (local_sock);
1279               return FOPEN_EXCL_ERR;
1280             }
1281         }
1282       if (!fp)
1283         {
1284           logprintf (LOG_NOTQUIET, "%s: %s\n", con->target, strerror (errno));
1285           fd_close (csock);
1286           con->csock = -1;
1287           fd_close (dtsock);
1288           fd_close (local_sock);
1289           return FOPENERR;
1290         }
1291     }
1292   else
1293     fp = output_stream;
1294
1295   if (passed_expected_bytes)
1296     {
1297       print_length (passed_expected_bytes, restval, true);
1298       expected_bytes = passed_expected_bytes;
1299         /* for fd_read_body's progress bar */
1300     }
1301   else if (expected_bytes)
1302     print_length (expected_bytes, restval, false);
1303
1304   /* Get the contents of the document.  */
1305   flags = 0;
1306   if (restval && rest_failed)
1307     flags |= rb_skip_startpos;
1308   rd_size = 0;
1309   res = fd_read_body (dtsock, fp,
1310                       expected_bytes ? expected_bytes - restval : 0,
1311                       restval, &rd_size, qtyread, &con->dltime, flags, warc_tmp);
1312
1313   tms = datetime_str (time (NULL));
1314   tmrate = retr_rate (rd_size, con->dltime);
1315   total_download_time += con->dltime;
1316
1317   fd_close (local_sock);
1318   /* Close the local file.  */
1319   if (!output_stream || con->cmd & DO_LIST)
1320     fclose (fp);
1321
1322   /* If fd_read_body couldn't write to fp or warc_tmp, bail out.  */
1323   if (res == -2 || (warc_tmp != NULL && res == -3))
1324     {
1325       logprintf (LOG_NOTQUIET, _("%s: %s, closing control connection.\n"),
1326                  con->target, strerror (errno));
1327       fd_close (csock);
1328       con->csock = -1;
1329       fd_close (dtsock);
1330       if (res == -2)
1331         return FWRITEERR;
1332       else if (res == -3)
1333         return WARC_TMP_FWRITEERR;
1334     }
1335   else if (res == -1)
1336     {
1337       logprintf (LOG_NOTQUIET, _("%s (%s) - Data connection: %s; "),
1338                  tms, tmrate, fd_errstr (dtsock));
1339       if (opt.server_response)
1340         logputs (LOG_ALWAYS, "\n");
1341     }
1342   fd_close (dtsock);
1343
1344   /* Get the server to tell us if everything is retrieved.  */
1345   err = ftp_response (csock, &respline);
1346   if (err != FTPOK)
1347     {
1348       /* The control connection is decidedly closed.  Print the time
1349          only if it hasn't already been printed.  */
1350       if (res != -1)
1351         logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
1352       logputs (LOG_NOTQUIET, _("Control connection closed.\n"));
1353       /* If there is an error on the control connection, close it, but
1354          return FTPRETRINT, since there is a possibility that the
1355          whole file was retrieved nevertheless (but that is for
1356          ftp_loop_internal to decide).  */
1357       fd_close (csock);
1358       con->csock = -1;
1359       return FTPRETRINT;
1360     } /* err != FTPOK */
1361   /* If retrieval failed for any reason, return FTPRETRINT, but do not
1362      close socket, since the control connection is still alive.  If
1363      there is something wrong with the control connection, it will
1364      become apparent later.  */
1365   if (*respline != '2')
1366     {
1367       xfree (respline);
1368       if (res != -1)
1369         logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
1370       logputs (LOG_NOTQUIET, _("Data transfer aborted.\n"));
1371       return FTPRETRINT;
1372     }
1373   xfree (respline);
1374
1375   if (res == -1)
1376     {
1377       /* What now?  The data connection was erroneous, whereas the
1378          response says everything is OK.  We shall play it safe.  */
1379       return FTPRETRINT;
1380     }
1381
1382   if (!(cmd & LEAVE_PENDING))
1383     {
1384       /* Closing the socket is faster than sending 'QUIT' and the
1385          effect is the same.  */
1386       fd_close (csock);
1387       con->csock = -1;
1388     }
1389   /* If it was a listing, and opt.server_response is true,
1390      print it out.  */
1391   if (con->cmd & DO_LIST)
1392     {
1393       if (opt.server_response)
1394         {
1395 /* 2005-02-25 SMS.
1396    Much of this work may already have been done, but repeating it should
1397    do no damage beyond wasting time.
1398 */
1399 /* On VMS, alter the name as required. */
1400 #ifdef __VMS
1401       char *targ;
1402
1403       targ = ods_conform( con->target);
1404       if (targ != con->target)
1405         {
1406           xfree( con->target);
1407           con->target = targ;
1408         }
1409 #endif /* def __VMS */
1410
1411       mkalldirs (con->target);
1412       fp = fopen (con->target, "r");
1413       if (!fp)
1414         logprintf (LOG_ALWAYS, "%s: %s\n", con->target, strerror (errno));
1415       else
1416         {
1417           char *line = NULL;
1418           size_t bufsize = 0;
1419           ssize_t len;
1420
1421           /* The lines are being read with getline because of
1422              no-buffering on opt.lfile.  */
1423           while ((len = getline (&line, &bufsize, fp)) > 0)
1424             {
1425               while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r'))
1426                 line[--len] = '\0';
1427               logprintf (LOG_ALWAYS, "%s\n",
1428                          quotearg_style (escape_quoting_style, line));
1429             }
1430           xfree (line);
1431           fclose (fp);
1432         }
1433         } /* server_response */
1434
1435       /* 2013-10-17 Andrea Urbani (matfanjol)
1436          < __LIST_A_EXPLANATION__ >
1437           After the SYST command, looks if it knows that system.
1438           If yes, wget will force the use of "LIST" or "LIST -a".
1439           If no, wget will try, only the first time of each session, before the
1440           "LIST -a" command and after the "LIST".
1441           If "LIST -a" works and returns more or equal data of the "LIST",
1442           "LIST -a" will be the standard list command for all the session.
1443           If "LIST -a" fails or returns less data than "LIST" (think on the case
1444           of an existing file called "-a"), "LIST" will be the standard list
1445           command for all the session.
1446           ("LIST -a" is used to get also the hidden files)
1447
1448           */
1449       if (!(con->st & LIST_AFTER_LIST_A_CHECK_DONE))
1450         {
1451           /* We still have to check "LIST" after the first "LIST -a" to see
1452              if with "LIST" we get more data than "LIST -a", that means
1453              "LIST -a" returned files/folders with "-a" name. */
1454           if (con->st & AVOID_LIST_A)
1455             {
1456               /* LIST was used in this cycle.
1457                  Let's see the result. */
1458               if (rd_size > previous_rd_size)
1459                 {
1460                   /* LIST returns more data than "LIST -a".
1461                      "LIST" is the official command to use. */
1462                   con->st |= LIST_AFTER_LIST_A_CHECK_DONE;
1463                   DEBUGP (("LIST returned more data than \"LIST -a\": "
1464                            "I will use \"LIST\" as standard list command\n"));
1465                 }
1466               else if (previous_rd_size > rd_size)
1467                 {
1468                   /* "LIST -a" returned more data then LIST.
1469                      "LIST -a" is the official command to use. */
1470                   con->st |= LIST_AFTER_LIST_A_CHECK_DONE;
1471                   con->st |= AVOID_LIST;
1472                   con->st &= ~AVOID_LIST_A;
1473                   /* Sorry, please, download again the "LIST -a"... */
1474                   try_again = true;
1475                   DEBUGP (("LIST returned less data than \"LIST -a\": I will "
1476                            "use \"LIST -a\" as standard list command\n"));
1477                 }
1478               else
1479                 {
1480                   /* LIST and "LIST -a" return the same data. */
1481                   if (rd_size == 0)
1482                     {
1483                       /* Same empty data. We will check both again because
1484                          we cannot check if "LIST -a" has returned an empty
1485                          folder instead of a folder content. */
1486                       con->st &= ~AVOID_LIST_A;
1487                     }
1488                   else
1489                     {
1490                       /* Same data, so, better to take "LIST -a" that
1491                          shows also hidden files/folders (when present) */
1492                       con->st |= LIST_AFTER_LIST_A_CHECK_DONE;
1493                       con->st |= AVOID_LIST;
1494                       con->st &= ~AVOID_LIST_A;
1495                       DEBUGP (("LIST returned the same amount of data of "
1496                                "\"LIST -a\": I will use \"LIST -a\" as standard "
1497                                "list command\n"));
1498                     }
1499                 }
1500             }
1501           else
1502             {
1503               /* In this cycle "LIST -a" should being used. Is it true? */
1504               if (list_a_used)
1505                 {
1506                   /* Yes, it is.
1507                      OK, let's save the amount of data and try again
1508                      with LIST */
1509                   previous_rd_size = rd_size;
1510                   try_again = true;
1511                   con->st |= AVOID_LIST_A;
1512                 }
1513               else
1514                 {
1515                   /* No: something happens and LIST was used.
1516                      This means "LIST -a" raises an error. */
1517                   con->st |= LIST_AFTER_LIST_A_CHECK_DONE;
1518                   con->st |= AVOID_LIST_A;
1519                   DEBUGP (("\"LIST -a\" failed: I will use \"LIST\" "
1520                            "as standard list command\n"));
1521                 }
1522             }
1523         }
1524     }
1525   } while (try_again);
1526   return RETRFINISHED;
1527 }
1528
1529 /* A one-file FTP loop.  This is the part where FTP retrieval is
1530    retried, and retried, and retried, and...
1531
1532    This loop either gets commands from con, or (if ON_YOUR_OWN is
1533    set), makes them up to retrieve the file given by the URL.  */
1534 static uerr_t
1535 ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con, char **local_file)
1536 {
1537   int count, orig_lp;
1538   wgint restval, len = 0, qtyread = 0;
1539   char *tms, *locf;
1540   const char *tmrate = NULL;
1541   uerr_t err;
1542   struct_stat st;
1543
1544   /* Declare WARC variables. */
1545   bool warc_enabled = (opt.warc_filename != NULL);
1546   FILE *warc_tmp = NULL;
1547   ip_address *warc_ip = NULL;
1548
1549   /* Get the target, and set the name for the message accordingly. */
1550   if ((f == NULL) && (con->target))
1551     {
1552       /* Explicit file (like ".listing"). */
1553       locf = con->target;
1554     }
1555   else
1556     {
1557       /* URL-derived file.  Consider "-O file" name. */
1558       con->target = url_file_name (u, NULL);
1559       if (!opt.output_document)
1560         locf = con->target;
1561       else
1562         locf = opt.output_document;
1563     }
1564
1565   /* If the output_document was given, then this check was already done and
1566      the file didn't exist. Hence the !opt.output_document */
1567
1568   /* If we receive .listing file it is necessary to determine system type of the ftp
1569      server even if opn.noclobber is given. Thus we must ignore opt.noclobber in
1570      order to establish connection with the server and get system type. */
1571   if (opt.noclobber && !opt.output_document && file_exists_p (con->target)
1572       && !((con->cmd & DO_LIST) && !(con->cmd & DO_RETR)))
1573     {
1574       logprintf (LOG_VERBOSE,
1575                  _("File %s already there; not retrieving.\n"), quote (con->target));
1576       /* If the file is there, we suppose it's retrieved OK.  */
1577       return RETROK;
1578     }
1579
1580   /* Remove it if it's a link.  */
1581   remove_link (con->target);
1582
1583   count = 0;
1584
1585   if (con->st & ON_YOUR_OWN)
1586     con->st = ON_YOUR_OWN;
1587
1588   orig_lp = con->cmd & LEAVE_PENDING ? 1 : 0;
1589
1590   /* THE loop.  */
1591   do
1592     {
1593       /* Increment the pass counter.  */
1594       ++count;
1595       sleep_between_retrievals (count);
1596       if (con->st & ON_YOUR_OWN)
1597         {
1598           con->cmd = 0;
1599           con->cmd |= (DO_RETR | LEAVE_PENDING);
1600           if (con->csock != -1)
1601             con->cmd &= ~ (DO_LOGIN | DO_CWD);
1602           else
1603             con->cmd |= (DO_LOGIN | DO_CWD);
1604         }
1605       else /* not on your own */
1606         {
1607           if (con->csock != -1)
1608             con->cmd &= ~DO_LOGIN;
1609           else
1610             con->cmd |= DO_LOGIN;
1611           if (con->st & DONE_CWD)
1612             con->cmd &= ~DO_CWD;
1613           else
1614             con->cmd |= DO_CWD;
1615         }
1616
1617       /* For file RETR requests, we can write a WARC record.
1618          We record the file contents to a temporary file. */
1619       if (warc_enabled && (con->cmd & DO_RETR) && warc_tmp == NULL)
1620         {
1621           warc_tmp = warc_tempfile ();
1622           if (warc_tmp == NULL)
1623             return WARC_TMP_FOPENERR;
1624
1625           if (!con->proxy && con->csock != -1)
1626             {
1627               warc_ip = (ip_address *) alloca (sizeof (ip_address));
1628               socket_ip_address (con->csock, warc_ip, ENDPOINT_PEER);
1629             }
1630         }
1631
1632       /* Decide whether or not to restart.  */
1633       if (con->cmd & DO_LIST)
1634         restval = 0;
1635       else if (opt.always_rest
1636           && stat (locf, &st) == 0
1637           && S_ISREG (st.st_mode))
1638         /* When -c is used, continue from on-disk size.  (Can't use
1639            hstat.len even if count>1 because we don't want a failed
1640            first attempt to clobber existing data.)  */
1641         restval = st.st_size;
1642       else if (count > 1)
1643         restval = qtyread;          /* start where the previous run left off */
1644       else
1645         restval = 0;
1646
1647       /* Get the current time string.  */
1648       tms = datetime_str (time (NULL));
1649       /* Print fetch message, if opt.verbose.  */
1650       if (opt.verbose)
1651         {
1652           char *hurl = url_string (u, URL_AUTH_HIDE_PASSWD);
1653           char tmp[256];
1654           strcpy (tmp, "        ");
1655           if (count > 1)
1656             sprintf (tmp, _("(try:%2d)"), count);
1657           logprintf (LOG_VERBOSE, "--%s--  %s\n  %s => %s\n",
1658                      tms, hurl, tmp, quote (locf));
1659 #ifdef WINDOWS
1660           ws_changetitle (hurl);
1661 #endif
1662           xfree (hurl);
1663         }
1664       /* Send getftp the proper length, if fileinfo was provided.  */
1665       if (f && f->type != FT_SYMLINK)
1666         len = f->size;
1667       else
1668         len = 0;
1669
1670       /* If we are working on a WARC record, getftp should also write
1671          to the warc_tmp file. */
1672       err = getftp (u, len, &qtyread, restval, con, count, warc_tmp);
1673
1674       if (con->csock == -1)
1675         con->st &= ~DONE_CWD;
1676       else
1677         con->st |= DONE_CWD;
1678
1679       switch (err)
1680         {
1681         case HOSTERR: case CONIMPOSSIBLE: case FWRITEERR: case FOPENERR:
1682         case FTPNSFOD: case FTPLOGINC: case FTPNOPASV: case CONTNOTSUPPORTED:
1683         case UNLINKERR: case WARC_TMP_FWRITEERR:
1684           /* Fatal errors, give up.  */
1685           if (warc_tmp != NULL)
1686             fclose (warc_tmp);
1687           return err;
1688         case CONSOCKERR: case CONERROR: case FTPSRVERR: case FTPRERR:
1689         case WRITEFAILED: case FTPUNKNOWNTYPE: case FTPSYSERR:
1690         case FTPPORTERR: case FTPLOGREFUSED: case FTPINVPASV:
1691         case FOPEN_EXCL_ERR:
1692           printwhat (count, opt.ntry);
1693           /* non-fatal errors */
1694           if (err == FOPEN_EXCL_ERR)
1695             {
1696               /* Re-determine the file name. */
1697               xfree_null (con->target);
1698               con->target = url_file_name (u, NULL);
1699               locf = con->target;
1700             }
1701           continue;
1702         case FTPRETRINT:
1703           /* If the control connection was closed, the retrieval
1704              will be considered OK if f->size == len.  */
1705           if (!f || qtyread != f->size)
1706             {
1707               printwhat (count, opt.ntry);
1708               continue;
1709             }
1710           break;
1711         case RETRFINISHED:
1712           /* Great!  */
1713           break;
1714         default:
1715           /* Not as great.  */
1716           abort ();
1717         }
1718       tms = datetime_str (time (NULL));
1719       if (!opt.spider)
1720         tmrate = retr_rate (qtyread - restval, con->dltime);
1721
1722       /* If we get out of the switch above without continue'ing, we've
1723          successfully downloaded a file.  Remember this fact. */
1724       downloaded_file (FILE_DOWNLOADED_NORMALLY, locf);
1725
1726       if (con->st & ON_YOUR_OWN)
1727         {
1728           fd_close (con->csock);
1729           con->csock = -1;
1730         }
1731       if (!opt.spider)
1732         {
1733           bool write_to_stdout = (opt.output_document && HYPHENP (opt.output_document));
1734
1735           logprintf (LOG_VERBOSE,
1736                      write_to_stdout
1737                      ? _("%s (%s) - written to stdout %s[%s]\n\n")
1738                      : _("%s (%s) - %s saved [%s]\n\n"),
1739                      tms, tmrate,
1740                      write_to_stdout ? "" : quote (locf),
1741                      number_to_static_string (qtyread));
1742         }
1743       if (!opt.verbose && !opt.quiet)
1744         {
1745           /* Need to hide the password from the URL.  The `if' is here
1746              so that we don't do the needless allocation every
1747              time. */
1748           char *hurl = url_string (u, URL_AUTH_HIDE_PASSWD);
1749           logprintf (LOG_NONVERBOSE, "%s URL: %s [%s] -> \"%s\" [%d]\n",
1750                      tms, hurl, number_to_static_string (qtyread), locf, count);
1751           xfree (hurl);
1752         }
1753
1754       if (warc_enabled && (con->cmd & DO_RETR))
1755         {
1756           /* Create and store a WARC resource record for the retrieved file. */
1757           bool warc_res;
1758
1759           warc_res = warc_write_resource_record (NULL, u->url, NULL, NULL,
1760                                                   warc_ip, NULL, warc_tmp, -1);
1761           if (! warc_res)
1762             return WARC_ERR;
1763
1764           /* warc_write_resource_record has also closed warc_tmp. */
1765         }
1766
1767       if (con->cmd & DO_LIST)
1768         /* This is a directory listing file. */
1769         {
1770           if (!opt.remove_listing)
1771             /* --dont-remove-listing was specified, so do count this towards the
1772                number of bytes and files downloaded. */
1773             {
1774               total_downloaded_bytes += qtyread;
1775               numurls++;
1776             }
1777
1778           /* Deletion of listing files is not controlled by --delete-after, but
1779              by the more specific option --dont-remove-listing, and the code
1780              to do this deletion is in another function. */
1781         }
1782       else if (!opt.spider)
1783         /* This is not a directory listing file. */
1784         {
1785           /* Unlike directory listing files, don't pretend normal files weren't
1786              downloaded if they're going to be deleted.  People seeding proxies,
1787              for instance, may want to know how many bytes and files they've
1788              downloaded through it. */
1789           total_downloaded_bytes += qtyread;
1790           numurls++;
1791
1792           if (opt.delete_after && !input_file_url (opt.input_filename))
1793             {
1794               DEBUGP (("\
1795 Removing file due to --delete-after in ftp_loop_internal():\n"));
1796               logprintf (LOG_VERBOSE, _("Removing %s.\n"), locf);
1797               if (unlink (locf))
1798                 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1799             }
1800         }
1801
1802       /* Restore the original leave-pendingness.  */
1803       if (orig_lp)
1804         con->cmd |= LEAVE_PENDING;
1805       else
1806         con->cmd &= ~LEAVE_PENDING;
1807
1808       if (local_file)
1809         *local_file = xstrdup (locf);
1810
1811       return RETROK;
1812     } while (!opt.ntry || (count < opt.ntry));
1813
1814   if (con->csock != -1 && (con->st & ON_YOUR_OWN))
1815     {
1816       fd_close (con->csock);
1817       con->csock = -1;
1818     }
1819   return TRYLIMEXC;
1820 }
1821
1822 /* Return the directory listing in a reusable format.  The directory
1823    is specifed in u->dir.  */
1824 static uerr_t
1825 ftp_get_listing (struct url *u, ccon *con, struct fileinfo **f)
1826 {
1827   uerr_t err;
1828   char *uf;                     /* url file name */
1829   char *lf;                     /* list file name */
1830   char *old_target = con->target;
1831
1832   con->st &= ~ON_YOUR_OWN;
1833   con->cmd |= (DO_LIST | LEAVE_PENDING);
1834   con->cmd &= ~DO_RETR;
1835
1836   /* Find the listing file name.  We do it by taking the file name of
1837      the URL and replacing the last component with the listing file
1838      name.  */
1839   uf = url_file_name (u, NULL);
1840   lf = file_merge (uf, LIST_FILENAME);
1841   xfree (uf);
1842   DEBUGP ((_("Using %s as listing tmp file.\n"), quote (lf)));
1843
1844   con->target = xstrdup (lf);
1845   xfree (lf);
1846   err = ftp_loop_internal (u, NULL, con, NULL);
1847   lf = xstrdup (con->target);
1848   xfree (con->target);
1849   con->target = old_target;
1850
1851   if (err == RETROK)
1852     {
1853       *f = ftp_parse_ls (lf, con->rs);
1854       if (opt.remove_listing)
1855         {
1856           if (unlink (lf))
1857             logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1858           else
1859             logprintf (LOG_VERBOSE, _("Removed %s.\n"), quote (lf));
1860         }
1861     }
1862   else
1863     *f = NULL;
1864   xfree (lf);
1865   con->cmd &= ~DO_LIST;
1866   return err;
1867 }
1868
1869 static uerr_t ftp_retrieve_dirs (struct url *, struct fileinfo *, ccon *);
1870 static uerr_t ftp_retrieve_glob (struct url *, ccon *, int);
1871 static struct fileinfo *delelement (struct fileinfo *, struct fileinfo **);
1872 static void freefileinfo (struct fileinfo *f);
1873
1874 /* Retrieve a list of files given in struct fileinfo linked list.  If
1875    a file is a symbolic link, do not retrieve it, but rather try to
1876    set up a similar link on the local disk, if the symlinks are
1877    supported.
1878
1879    If opt.recursive is set, after all files have been retrieved,
1880    ftp_retrieve_dirs will be called to retrieve the directories.  */
1881 static uerr_t
1882 ftp_retrieve_list (struct url *u, struct fileinfo *f, ccon *con)
1883 {
1884   static int depth = 0;
1885   uerr_t err;
1886   struct fileinfo *orig;
1887   wgint local_size;
1888   time_t tml;
1889   bool dlthis; /* Download this (file). */
1890   const char *actual_target = NULL;
1891
1892   /* Increase the depth.  */
1893   ++depth;
1894   if (opt.reclevel != INFINITE_RECURSION && depth > opt.reclevel)
1895     {
1896       DEBUGP ((_("Recursion depth %d exceeded max. depth %d.\n"),
1897                depth, opt.reclevel));
1898       --depth;
1899       return RECLEVELEXC;
1900     }
1901
1902   assert (f != NULL);
1903   orig = f;
1904
1905   con->st &= ~ON_YOUR_OWN;
1906   if (!(con->st & DONE_CWD))
1907     con->cmd |= DO_CWD;
1908   else
1909     con->cmd &= ~DO_CWD;
1910   con->cmd |= (DO_RETR | LEAVE_PENDING);
1911
1912   if (con->csock < 0)
1913     con->cmd |= DO_LOGIN;
1914   else
1915     con->cmd &= ~DO_LOGIN;
1916
1917   err = RETROK;                 /* in case it's not used */
1918
1919   while (f)
1920     {
1921       char *old_target, *ofile;
1922
1923       if (opt.quota && total_downloaded_bytes > opt.quota)
1924         {
1925           --depth;
1926           return QUOTEXC;
1927         }
1928       old_target = con->target;
1929
1930       ofile = xstrdup (u->file);
1931       url_set_file (u, f->name);
1932
1933       con->target = url_file_name (u, NULL);
1934       err = RETROK;
1935
1936       dlthis = true;
1937       if (opt.timestamping && f->type == FT_PLAINFILE)
1938         {
1939           struct_stat st;
1940           /* If conversion of HTML files retrieved via FTP is ever implemented,
1941              we'll need to stat() <file>.orig here when -K has been specified.
1942              I'm not implementing it now since files on an FTP server are much
1943              more likely than files on an HTTP server to legitimately have a
1944              .orig suffix. */
1945           if (!stat (con->target, &st))
1946             {
1947               bool eq_size;
1948               bool cor_val;
1949               /* Else, get it from the file.  */
1950               local_size = st.st_size;
1951               tml = st.st_mtime;
1952 #ifdef WINDOWS
1953               /* Modification time granularity is 2 seconds for Windows, so
1954                  increase local time by 1 second for later comparison. */
1955               tml++;
1956 #endif
1957               /* Compare file sizes only for servers that tell us correct
1958                  values. Assume sizes being equal for servers that lie
1959                  about file size.  */
1960               cor_val = (con->rs == ST_UNIX || con->rs == ST_WINNT);
1961               eq_size = cor_val ? (local_size == f->size) : true;
1962               if (f->tstamp <= tml && eq_size)
1963                 {
1964                   /* Remote file is older, file sizes can be compared and
1965                      are both equal. */
1966                   logprintf (LOG_VERBOSE, _("\
1967 Remote file no newer than local file %s -- not retrieving.\n"), quote (con->target));
1968                   dlthis = false;
1969                 }
1970               else if (eq_size)
1971                 {
1972                   /* Remote file is newer or sizes cannot be matched */
1973                   logprintf (LOG_VERBOSE, _("\
1974 Remote file is newer than local file %s -- retrieving.\n\n"),
1975                              quote (con->target));
1976                 }
1977               else
1978                 {
1979                   /* Sizes do not match */
1980                   logprintf (LOG_VERBOSE, _("\
1981 The sizes do not match (local %s) -- retrieving.\n\n"),
1982                              number_to_static_string (local_size));
1983                 }
1984             }
1985         }       /* opt.timestamping && f->type == FT_PLAINFILE */
1986       switch (f->type)
1987         {
1988         case FT_SYMLINK:
1989           /* If opt.retr_symlinks is defined, we treat symlinks as
1990              if they were normal files.  There is currently no way
1991              to distinguish whether they might be directories, and
1992              follow them.  */
1993           if (!opt.retr_symlinks)
1994             {
1995 #ifdef HAVE_SYMLINK
1996               if (!f->linkto)
1997                 logputs (LOG_NOTQUIET,
1998                          _("Invalid name of the symlink, skipping.\n"));
1999               else
2000                 {
2001                   struct_stat st;
2002                   /* Check whether we already have the correct
2003                      symbolic link.  */
2004                   int rc = lstat (con->target, &st);
2005                   if (rc == 0)
2006                     {
2007                       size_t len = strlen (f->linkto) + 1;
2008                       if (S_ISLNK (st.st_mode))
2009                         {
2010                           char *link_target = (char *)alloca (len);
2011                           size_t n = readlink (con->target, link_target, len);
2012                           if ((n == len - 1)
2013                               && (memcmp (link_target, f->linkto, n) == 0))
2014                             {
2015                               logprintf (LOG_VERBOSE, _("\
2016 Already have correct symlink %s -> %s\n\n"),
2017                                          quote (con->target),
2018                                          quote (f->linkto));
2019                               dlthis = false;
2020                               break;
2021                             }
2022                         }
2023                     }
2024                   logprintf (LOG_VERBOSE, _("Creating symlink %s -> %s\n"),
2025                              quote (con->target), quote (f->linkto));
2026                   /* Unlink before creating symlink!  */
2027                   unlink (con->target);
2028                   if (symlink (f->linkto, con->target) == -1)
2029                     logprintf (LOG_NOTQUIET, "symlink: %s\n", strerror (errno));
2030                   logputs (LOG_VERBOSE, "\n");
2031                 } /* have f->linkto */
2032 #else  /* not HAVE_SYMLINK */
2033               logprintf (LOG_NOTQUIET,
2034                          _("Symlinks not supported, skipping symlink %s.\n"),
2035                          quote (con->target));
2036 #endif /* not HAVE_SYMLINK */
2037             }
2038           else                /* opt.retr_symlinks */
2039             {
2040               if (dlthis)
2041                 err = ftp_loop_internal (u, f, con, NULL);
2042             } /* opt.retr_symlinks */
2043           break;
2044         case FT_DIRECTORY:
2045           if (!opt.recursive)
2046             logprintf (LOG_NOTQUIET, _("Skipping directory %s.\n"),
2047                        quote (f->name));
2048           break;
2049         case FT_PLAINFILE:
2050           /* Call the retrieve loop.  */
2051           if (dlthis)
2052             err = ftp_loop_internal (u, f, con, NULL);
2053           break;
2054         case FT_UNKNOWN:
2055           logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
2056                      quote (f->name));
2057           break;
2058         }       /* switch */
2059
2060
2061       /* 2004-12-15 SMS.
2062        * Set permissions _before_ setting the times, as setting the
2063        * permissions changes the modified-time, at least on VMS.
2064        * Also, use the opt.output_document name here, too, as
2065        * appropriate.  (Do the test once, and save the result.)
2066        */
2067
2068       set_local_file (&actual_target, con->target);
2069
2070       /* If downloading a plain file, and the user requested it, then
2071          set valid (non-zero) permissions. */
2072       if (dlthis && (actual_target != NULL) &&
2073        (f->type == FT_PLAINFILE) && opt.preserve_perm)
2074         {
2075           if (f->perms)
2076             chmod (actual_target, f->perms);
2077           else
2078             DEBUGP (("Unrecognized permissions for %s.\n", actual_target));
2079         }
2080
2081       /* Set the time-stamp information to the local file.  Symlinks
2082          are not to be stamped because it sets the stamp on the
2083          original.  :( */
2084       if (actual_target != NULL)
2085         {
2086           if (opt.useservertimestamps
2087               && !(f->type == FT_SYMLINK && !opt.retr_symlinks)
2088               && f->tstamp != -1
2089               && dlthis
2090               && file_exists_p (con->target))
2091             {
2092               touch (actual_target, f->tstamp);
2093             }
2094           else if (f->tstamp == -1)
2095             logprintf (LOG_NOTQUIET, _("%s: corrupt time-stamp.\n"),
2096                        actual_target);
2097         }
2098
2099       xfree (con->target);
2100       con->target = old_target;
2101
2102       url_set_file (u, ofile);
2103       xfree (ofile);
2104
2105       /* Break on fatals.  */
2106       if (err == QUOTEXC || err == HOSTERR || err == FWRITEERR
2107           || err == WARC_ERR || err == WARC_TMP_FOPENERR
2108           || err == WARC_TMP_FWRITEERR)
2109         break;
2110       con->cmd &= ~ (DO_CWD | DO_LOGIN);
2111       f = f->next;
2112     }
2113
2114   /* We do not want to call ftp_retrieve_dirs here */
2115   if (opt.recursive &&
2116       !(opt.reclevel != INFINITE_RECURSION && depth >= opt.reclevel))
2117     err = ftp_retrieve_dirs (u, orig, con);
2118   else if (opt.recursive)
2119     DEBUGP ((_("Will not retrieve dirs since depth is %d (max %d).\n"),
2120              depth, opt.reclevel));
2121   --depth;
2122   return err;
2123 }
2124
2125 /* Retrieve the directories given in a file list.  This function works
2126    by simply going through the linked list and calling
2127    ftp_retrieve_glob on each directory entry.  The function knows
2128    about excluded directories.  */
2129 static uerr_t
2130 ftp_retrieve_dirs (struct url *u, struct fileinfo *f, ccon *con)
2131 {
2132   char *container = NULL;
2133   int container_size = 0;
2134
2135   for (; f; f = f->next)
2136     {
2137       int size;
2138       char *odir, *newdir;
2139
2140       if (opt.quota && total_downloaded_bytes > opt.quota)
2141         break;
2142       if (f->type != FT_DIRECTORY)
2143         continue;
2144
2145       /* Allocate u->dir off stack, but reallocate only if a larger
2146          string is needed.  It's a pity there's no "realloca" for an
2147          item on the bottom of the stack.  */
2148       size = strlen (u->dir) + 1 + strlen (f->name) + 1;
2149       if (size > container_size)
2150         container = (char *)alloca (size);
2151       newdir = container;
2152
2153       odir = u->dir;
2154       if (*odir == '\0'
2155           || (*odir == '/' && *(odir + 1) == '\0'))
2156         /* If ODIR is empty or just "/", simply append f->name to
2157            ODIR.  (In the former case, to preserve u->dir being
2158            relative; in the latter case, to avoid double slash.)  */
2159         sprintf (newdir, "%s%s", odir, f->name);
2160       else
2161         /* Else, use a separator. */
2162         sprintf (newdir, "%s/%s", odir, f->name);
2163
2164       DEBUGP (("Composing new CWD relative to the initial directory.\n"));
2165       DEBUGP (("  odir = '%s'\n  f->name = '%s'\n  newdir = '%s'\n\n",
2166                odir, f->name, newdir));
2167       if (!accdir (newdir))
2168         {
2169           logprintf (LOG_VERBOSE, _("\
2170 Not descending to %s as it is excluded/not-included.\n"),
2171                      quote (newdir));
2172           continue;
2173         }
2174
2175       con->st &= ~DONE_CWD;
2176
2177       odir = xstrdup (u->dir);  /* because url_set_dir will free
2178                                    u->dir. */
2179       url_set_dir (u, newdir);
2180       ftp_retrieve_glob (u, con, GLOB_GETALL);
2181       url_set_dir (u, odir);
2182       xfree (odir);
2183
2184       /* Set the time-stamp?  */
2185     }
2186
2187   if (opt.quota && total_downloaded_bytes > opt.quota)
2188     return QUOTEXC;
2189   else
2190     return RETROK;
2191 }
2192
2193 /* Return true if S has a leading '/'  or contains '../' */
2194 static bool
2195 has_insecure_name_p (const char *s)
2196 {
2197   if (*s == '/')
2198     return true;
2199
2200   if (strstr (s, "../") != 0)
2201     return true;
2202
2203   return false;
2204 }
2205
2206 /* A near-top-level function to retrieve the files in a directory.
2207    The function calls ftp_get_listing, to get a linked list of files.
2208    Then it weeds out the file names that do not match the pattern.
2209    ftp_retrieve_list is called with this updated list as an argument.
2210
2211    If the argument ACTION is GLOB_GETONE, just download the file (but
2212    first get the listing, so that the time-stamp is heeded); if it's
2213    GLOB_GLOBALL, use globbing; if it's GLOB_GETALL, download the whole
2214    directory.  */
2215 static uerr_t
2216 ftp_retrieve_glob (struct url *u, ccon *con, int action)
2217 {
2218   struct fileinfo *f, *start;
2219   uerr_t res;
2220
2221   con->cmd |= LEAVE_PENDING;
2222
2223   res = ftp_get_listing (u, con, &start);
2224   if (res != RETROK)
2225     return res;
2226   /* First: weed out that do not conform the global rules given in
2227      opt.accepts and opt.rejects.  */
2228   if (opt.accepts || opt.rejects)
2229     {
2230       f = start;
2231       while (f)
2232         {
2233           if (f->type != FT_DIRECTORY && !acceptable (f->name))
2234             {
2235               logprintf (LOG_VERBOSE, _("Rejecting %s.\n"),
2236                          quote (f->name));
2237               f = delelement (f, &start);
2238             }
2239           else
2240             f = f->next;
2241         }
2242     }
2243   /* Remove all files with possible harmful names */
2244   f = start;
2245   while (f)
2246     {
2247       if (has_insecure_name_p (f->name))
2248         {
2249           logprintf (LOG_VERBOSE, _("Rejecting %s.\n"),
2250                      quote (f->name));
2251           f = delelement (f, &start);
2252         }
2253       else
2254         f = f->next;
2255     }
2256   /* Now weed out the files that do not match our globbing pattern.
2257      If we are dealing with a globbing pattern, that is.  */
2258   if (*u->file)
2259     {
2260       if (action == GLOB_GLOBALL)
2261         {
2262           int (*matcher) (const char *, const char *, int)
2263             = opt.ignore_case ? fnmatch_nocase : fnmatch;
2264           int matchres = 0;
2265
2266           f = start;
2267           while (f)
2268             {
2269               matchres = matcher (u->file, f->name, 0);
2270               if (matchres == -1)
2271                 {
2272                   logprintf (LOG_NOTQUIET, _("Error matching %s against %s: %s\n"),
2273                              u->file, quotearg_style (escape_quoting_style, f->name),
2274                              strerror (errno));
2275                   break;
2276                 }
2277               if (matchres == FNM_NOMATCH)
2278                 f = delelement (f, &start); /* delete the element from the list */
2279               else
2280                 f = f->next;        /* leave the element in the list */
2281             }
2282           if (matchres == -1)
2283             {
2284               freefileinfo (start);
2285               return RETRBADPATTERN;
2286             }
2287         }
2288       else if (action == GLOB_GETONE)
2289         {
2290 #ifdef __VMS
2291           /* 2009-09-09 SMS.
2292            * Odd-ball compiler ("HP C V7.3-009 on OpenVMS Alpha V7.3-2")
2293            * bug causes spurious %CC-E-BADCONDIT complaint with this
2294            * "?:" statement.  (Different linkage attributes for strcmp()
2295            * and strcasecmp().)  Converting to "if" changes the
2296            * complaint to %CC-W-PTRMISMATCH on "cmp = strcmp;".  Adding
2297            * the senseless type cast clears the complaint, and looks
2298            * harmless.
2299            */
2300           int (*cmp) (const char *, const char *)
2301             = opt.ignore_case ? strcasecmp : (int (*)())strcmp;
2302 #else /* def __VMS */
2303           int (*cmp) (const char *, const char *)
2304             = opt.ignore_case ? strcasecmp : strcmp;
2305 #endif /* def __VMS [else] */
2306           f = start;
2307           while (f)
2308             {
2309               if (0 != cmp(u->file, f->name))
2310                 f = delelement (f, &start);
2311               else
2312                 f = f->next;
2313             }
2314         }
2315     }
2316   if (start)
2317     {
2318       /* Just get everything.  */
2319       res = ftp_retrieve_list (u, start, con);
2320     }
2321   else
2322     {
2323       if (action == GLOB_GLOBALL)
2324         {
2325           /* No luck.  */
2326           /* #### This message SUCKS.  We should see what was the
2327              reason that nothing was retrieved.  */
2328           logprintf (LOG_VERBOSE, _("No matches on pattern %s.\n"),
2329                      quote (u->file));
2330         }
2331       else if (action == GLOB_GETONE) /* GLOB_GETONE or GLOB_GETALL */
2332         {
2333           /* Let's try retrieving it anyway.  */
2334           con->st |= ON_YOUR_OWN;
2335           res = ftp_loop_internal (u, NULL, con, NULL);
2336           return res;
2337         }
2338
2339       /* If action == GLOB_GETALL, and the file list is empty, there's
2340          no point in trying to download anything or in complaining about
2341          it.  (An empty directory should not cause complaints.)
2342       */
2343     }
2344   freefileinfo (start);
2345   if (opt.quota && total_downloaded_bytes > opt.quota)
2346     return QUOTEXC;
2347   else
2348     return res;
2349 }
2350
2351 /* The wrapper that calls an appropriate routine according to contents
2352    of URL.  Inherently, its capabilities are limited on what can be
2353    encoded into a URL.  */
2354 uerr_t
2355 ftp_loop (struct url *u, char **local_file, int *dt, struct url *proxy,
2356           bool recursive, bool glob)
2357 {
2358   ccon con;                     /* FTP connection */
2359   uerr_t res;
2360
2361   *dt = 0;
2362
2363   xzero (con);
2364
2365   con.csock = -1;
2366   con.st = ON_YOUR_OWN;
2367   con.rs = ST_UNIX;
2368   con.id = NULL;
2369   con.proxy = proxy;
2370
2371   /* If the file name is empty, the user probably wants a directory
2372      index.  We'll provide one, properly HTML-ized.  Unless
2373      opt.htmlify is 0, of course.  :-) */
2374   if (!*u->file && !recursive)
2375     {
2376       struct fileinfo *f;
2377       res = ftp_get_listing (u, &con, &f);
2378
2379       if (res == RETROK)
2380         {
2381           if (opt.htmlify && !opt.spider)
2382             {
2383               char *filename = (opt.output_document
2384                                 ? xstrdup (opt.output_document)
2385                                 : (con.target ? xstrdup (con.target)
2386                                    : url_file_name (u, NULL)));
2387               res = ftp_index (filename, u, f);
2388               if (res == FTPOK && opt.verbose)
2389                 {
2390                   if (!opt.output_document)
2391                     {
2392                       struct_stat st;
2393                       wgint sz;
2394                       if (stat (filename, &st) == 0)
2395                         sz = st.st_size;
2396                       else
2397                         sz = -1;
2398                       logprintf (LOG_NOTQUIET,
2399                                  _("Wrote HTML-ized index to %s [%s].\n"),
2400                                  quote (filename), number_to_static_string (sz));
2401                     }
2402                   else
2403                     logprintf (LOG_NOTQUIET,
2404                                _("Wrote HTML-ized index to %s.\n"),
2405                                quote (filename));
2406                 }
2407               xfree (filename);
2408             }
2409           freefileinfo (f);
2410         }
2411     }
2412   else
2413     {
2414       bool ispattern = false;
2415       if (glob)
2416         {
2417           /* Treat the URL as a pattern if the file name part of the
2418              URL path contains wildcards.  (Don't check for u->file
2419              because it is unescaped and therefore doesn't leave users
2420              the option to escape literal '*' as %2A.)  */
2421           char *file_part = strrchr (u->path, '/');
2422           if (!file_part)
2423             file_part = u->path;
2424           ispattern = has_wildcards_p (file_part);
2425         }
2426       if (ispattern || recursive || opt.timestamping || opt.preserve_perm)
2427         {
2428           /* ftp_retrieve_glob is a catch-all function that gets called
2429              if we need globbing, time-stamping, recursion or preserve
2430              permissions.  Its third argument is just what we really need.  */
2431           res = ftp_retrieve_glob (u, &con,
2432                                    ispattern ? GLOB_GLOBALL : GLOB_GETONE);
2433         }
2434       else
2435         res = ftp_loop_internal (u, NULL, &con, local_file);
2436     }
2437   if (res == FTPOK)
2438     res = RETROK;
2439   if (res == RETROK)
2440     *dt |= RETROKF;
2441   /* If a connection was left, quench it.  */
2442   if (con.csock != -1)
2443     fd_close (con.csock);
2444   xfree_null (con.id);
2445   con.id = NULL;
2446   xfree_null (con.target);
2447   con.target = NULL;
2448   return res;
2449 }
2450
2451 /* Delete an element from the fileinfo linked list.  Returns the
2452    address of the next element, or NULL if the list is exhausted.  It
2453    can modify the start of the list.  */
2454 static struct fileinfo *
2455 delelement (struct fileinfo *f, struct fileinfo **start)
2456 {
2457   struct fileinfo *prev = f->prev;
2458   struct fileinfo *next = f->next;
2459
2460   xfree (f->name);
2461   xfree_null (f->linkto);
2462   xfree (f);
2463
2464   if (next)
2465     next->prev = prev;
2466   if (prev)
2467     prev->next = next;
2468   else
2469     *start = next;
2470   return next;
2471 }
2472
2473 /* Free the fileinfo linked list of files.  */
2474 static void
2475 freefileinfo (struct fileinfo *f)
2476 {
2477   while (f)
2478     {
2479       struct fileinfo *next = f->next;
2480       xfree (f->name);
2481       if (f->linkto)
2482         xfree (f->linkto);
2483       xfree (f);
2484       f = next;
2485     }
2486 }