]> sjero.net Git - wget/blob - src/ftp.c
Make wget capable of starting downloads from a specified position.
[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.start_pos >= 0)
1636         restval = opt.start_pos;
1637       else if (opt.always_rest
1638           && stat (locf, &st) == 0
1639           && S_ISREG (st.st_mode))
1640         /* When -c is used, continue from on-disk size.  (Can't use
1641            hstat.len even if count>1 because we don't want a failed
1642            first attempt to clobber existing data.)  */
1643         restval = st.st_size;
1644       else if (count > 1)
1645         restval = qtyread;          /* start where the previous run left off */
1646       else
1647         restval = 0;
1648
1649       /* Get the current time string.  */
1650       tms = datetime_str (time (NULL));
1651       /* Print fetch message, if opt.verbose.  */
1652       if (opt.verbose)
1653         {
1654           char *hurl = url_string (u, URL_AUTH_HIDE_PASSWD);
1655           char tmp[256];
1656           strcpy (tmp, "        ");
1657           if (count > 1)
1658             sprintf (tmp, _("(try:%2d)"), count);
1659           logprintf (LOG_VERBOSE, "--%s--  %s\n  %s => %s\n",
1660                      tms, hurl, tmp, quote (locf));
1661 #ifdef WINDOWS
1662           ws_changetitle (hurl);
1663 #endif
1664           xfree (hurl);
1665         }
1666       /* Send getftp the proper length, if fileinfo was provided.  */
1667       if (f && f->type != FT_SYMLINK)
1668         len = f->size;
1669       else
1670         len = 0;
1671
1672       /* If we are working on a WARC record, getftp should also write
1673          to the warc_tmp file. */
1674       err = getftp (u, len, &qtyread, restval, con, count, warc_tmp);
1675
1676       if (con->csock == -1)
1677         con->st &= ~DONE_CWD;
1678       else
1679         con->st |= DONE_CWD;
1680
1681       switch (err)
1682         {
1683         case HOSTERR: case CONIMPOSSIBLE: case FWRITEERR: case FOPENERR:
1684         case FTPNSFOD: case FTPLOGINC: case FTPNOPASV: case CONTNOTSUPPORTED:
1685         case UNLINKERR: case WARC_TMP_FWRITEERR:
1686           /* Fatal errors, give up.  */
1687           if (warc_tmp != NULL)
1688             fclose (warc_tmp);
1689           return err;
1690         case CONSOCKERR: case CONERROR: case FTPSRVERR: case FTPRERR:
1691         case WRITEFAILED: case FTPUNKNOWNTYPE: case FTPSYSERR:
1692         case FTPPORTERR: case FTPLOGREFUSED: case FTPINVPASV:
1693         case FOPEN_EXCL_ERR:
1694           printwhat (count, opt.ntry);
1695           /* non-fatal errors */
1696           if (err == FOPEN_EXCL_ERR)
1697             {
1698               /* Re-determine the file name. */
1699               xfree_null (con->target);
1700               con->target = url_file_name (u, NULL);
1701               locf = con->target;
1702             }
1703           continue;
1704         case FTPRETRINT:
1705           /* If the control connection was closed, the retrieval
1706              will be considered OK if f->size == len.  */
1707           if (!f || qtyread != f->size)
1708             {
1709               printwhat (count, opt.ntry);
1710               continue;
1711             }
1712           break;
1713         case RETRFINISHED:
1714           /* Great!  */
1715           break;
1716         default:
1717           /* Not as great.  */
1718           abort ();
1719         }
1720       tms = datetime_str (time (NULL));
1721       if (!opt.spider)
1722         tmrate = retr_rate (qtyread - restval, con->dltime);
1723
1724       /* If we get out of the switch above without continue'ing, we've
1725          successfully downloaded a file.  Remember this fact. */
1726       downloaded_file (FILE_DOWNLOADED_NORMALLY, locf);
1727
1728       if (con->st & ON_YOUR_OWN)
1729         {
1730           fd_close (con->csock);
1731           con->csock = -1;
1732         }
1733       if (!opt.spider)
1734         {
1735           bool write_to_stdout = (opt.output_document && HYPHENP (opt.output_document));
1736
1737           logprintf (LOG_VERBOSE,
1738                      write_to_stdout
1739                      ? _("%s (%s) - written to stdout %s[%s]\n\n")
1740                      : _("%s (%s) - %s saved [%s]\n\n"),
1741                      tms, tmrate,
1742                      write_to_stdout ? "" : quote (locf),
1743                      number_to_static_string (qtyread));
1744         }
1745       if (!opt.verbose && !opt.quiet)
1746         {
1747           /* Need to hide the password from the URL.  The `if' is here
1748              so that we don't do the needless allocation every
1749              time. */
1750           char *hurl = url_string (u, URL_AUTH_HIDE_PASSWD);
1751           logprintf (LOG_NONVERBOSE, "%s URL: %s [%s] -> \"%s\" [%d]\n",
1752                      tms, hurl, number_to_static_string (qtyread), locf, count);
1753           xfree (hurl);
1754         }
1755
1756       if (warc_enabled && (con->cmd & DO_RETR))
1757         {
1758           /* Create and store a WARC resource record for the retrieved file. */
1759           bool warc_res;
1760
1761           warc_res = warc_write_resource_record (NULL, u->url, NULL, NULL,
1762                                                   warc_ip, NULL, warc_tmp, -1);
1763           if (! warc_res)
1764             return WARC_ERR;
1765
1766           /* warc_write_resource_record has also closed warc_tmp. */
1767         }
1768
1769       if (con->cmd & DO_LIST)
1770         /* This is a directory listing file. */
1771         {
1772           if (!opt.remove_listing)
1773             /* --dont-remove-listing was specified, so do count this towards the
1774                number of bytes and files downloaded. */
1775             {
1776               total_downloaded_bytes += qtyread;
1777               numurls++;
1778             }
1779
1780           /* Deletion of listing files is not controlled by --delete-after, but
1781              by the more specific option --dont-remove-listing, and the code
1782              to do this deletion is in another function. */
1783         }
1784       else if (!opt.spider)
1785         /* This is not a directory listing file. */
1786         {
1787           /* Unlike directory listing files, don't pretend normal files weren't
1788              downloaded if they're going to be deleted.  People seeding proxies,
1789              for instance, may want to know how many bytes and files they've
1790              downloaded through it. */
1791           total_downloaded_bytes += qtyread;
1792           numurls++;
1793
1794           if (opt.delete_after && !input_file_url (opt.input_filename))
1795             {
1796               DEBUGP (("\
1797 Removing file due to --delete-after in ftp_loop_internal():\n"));
1798               logprintf (LOG_VERBOSE, _("Removing %s.\n"), locf);
1799               if (unlink (locf))
1800                 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1801             }
1802         }
1803
1804       /* Restore the original leave-pendingness.  */
1805       if (orig_lp)
1806         con->cmd |= LEAVE_PENDING;
1807       else
1808         con->cmd &= ~LEAVE_PENDING;
1809
1810       if (local_file)
1811         *local_file = xstrdup (locf);
1812
1813       return RETROK;
1814     } while (!opt.ntry || (count < opt.ntry));
1815
1816   if (con->csock != -1 && (con->st & ON_YOUR_OWN))
1817     {
1818       fd_close (con->csock);
1819       con->csock = -1;
1820     }
1821   return TRYLIMEXC;
1822 }
1823
1824 /* Return the directory listing in a reusable format.  The directory
1825    is specifed in u->dir.  */
1826 static uerr_t
1827 ftp_get_listing (struct url *u, ccon *con, struct fileinfo **f)
1828 {
1829   uerr_t err;
1830   char *uf;                     /* url file name */
1831   char *lf;                     /* list file name */
1832   char *old_target = con->target;
1833
1834   con->st &= ~ON_YOUR_OWN;
1835   con->cmd |= (DO_LIST | LEAVE_PENDING);
1836   con->cmd &= ~DO_RETR;
1837
1838   /* Find the listing file name.  We do it by taking the file name of
1839      the URL and replacing the last component with the listing file
1840      name.  */
1841   uf = url_file_name (u, NULL);
1842   lf = file_merge (uf, LIST_FILENAME);
1843   xfree (uf);
1844   DEBUGP ((_("Using %s as listing tmp file.\n"), quote (lf)));
1845
1846   con->target = xstrdup (lf);
1847   xfree (lf);
1848   err = ftp_loop_internal (u, NULL, con, NULL);
1849   lf = xstrdup (con->target);
1850   xfree (con->target);
1851   con->target = old_target;
1852
1853   if (err == RETROK)
1854     {
1855       *f = ftp_parse_ls (lf, con->rs);
1856       if (opt.remove_listing)
1857         {
1858           if (unlink (lf))
1859             logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1860           else
1861             logprintf (LOG_VERBOSE, _("Removed %s.\n"), quote (lf));
1862         }
1863     }
1864   else
1865     *f = NULL;
1866   xfree (lf);
1867   con->cmd &= ~DO_LIST;
1868   return err;
1869 }
1870
1871 static uerr_t ftp_retrieve_dirs (struct url *, struct fileinfo *, ccon *);
1872 static uerr_t ftp_retrieve_glob (struct url *, ccon *, int);
1873 static struct fileinfo *delelement (struct fileinfo *, struct fileinfo **);
1874 static void freefileinfo (struct fileinfo *f);
1875
1876 /* Retrieve a list of files given in struct fileinfo linked list.  If
1877    a file is a symbolic link, do not retrieve it, but rather try to
1878    set up a similar link on the local disk, if the symlinks are
1879    supported.
1880
1881    If opt.recursive is set, after all files have been retrieved,
1882    ftp_retrieve_dirs will be called to retrieve the directories.  */
1883 static uerr_t
1884 ftp_retrieve_list (struct url *u, struct fileinfo *f, ccon *con)
1885 {
1886   static int depth = 0;
1887   uerr_t err;
1888   struct fileinfo *orig;
1889   wgint local_size;
1890   time_t tml;
1891   bool dlthis; /* Download this (file). */
1892   const char *actual_target = NULL;
1893
1894   /* Increase the depth.  */
1895   ++depth;
1896   if (opt.reclevel != INFINITE_RECURSION && depth > opt.reclevel)
1897     {
1898       DEBUGP ((_("Recursion depth %d exceeded max. depth %d.\n"),
1899                depth, opt.reclevel));
1900       --depth;
1901       return RECLEVELEXC;
1902     }
1903
1904   assert (f != NULL);
1905   orig = f;
1906
1907   con->st &= ~ON_YOUR_OWN;
1908   if (!(con->st & DONE_CWD))
1909     con->cmd |= DO_CWD;
1910   else
1911     con->cmd &= ~DO_CWD;
1912   con->cmd |= (DO_RETR | LEAVE_PENDING);
1913
1914   if (con->csock < 0)
1915     con->cmd |= DO_LOGIN;
1916   else
1917     con->cmd &= ~DO_LOGIN;
1918
1919   err = RETROK;                 /* in case it's not used */
1920
1921   while (f)
1922     {
1923       char *old_target, *ofile;
1924
1925       if (opt.quota && total_downloaded_bytes > opt.quota)
1926         {
1927           --depth;
1928           return QUOTEXC;
1929         }
1930       old_target = con->target;
1931
1932       ofile = xstrdup (u->file);
1933       url_set_file (u, f->name);
1934
1935       con->target = url_file_name (u, NULL);
1936       err = RETROK;
1937
1938       dlthis = true;
1939       if (opt.timestamping && f->type == FT_PLAINFILE)
1940         {
1941           struct_stat st;
1942           /* If conversion of HTML files retrieved via FTP is ever implemented,
1943              we'll need to stat() <file>.orig here when -K has been specified.
1944              I'm not implementing it now since files on an FTP server are much
1945              more likely than files on an HTTP server to legitimately have a
1946              .orig suffix. */
1947           if (!stat (con->target, &st))
1948             {
1949               bool eq_size;
1950               bool cor_val;
1951               /* Else, get it from the file.  */
1952               local_size = st.st_size;
1953               tml = st.st_mtime;
1954 #ifdef WINDOWS
1955               /* Modification time granularity is 2 seconds for Windows, so
1956                  increase local time by 1 second for later comparison. */
1957               tml++;
1958 #endif
1959               /* Compare file sizes only for servers that tell us correct
1960                  values. Assume sizes being equal for servers that lie
1961                  about file size.  */
1962               cor_val = (con->rs == ST_UNIX || con->rs == ST_WINNT);
1963               eq_size = cor_val ? (local_size == f->size) : true;
1964               if (f->tstamp <= tml && eq_size)
1965                 {
1966                   /* Remote file is older, file sizes can be compared and
1967                      are both equal. */
1968                   logprintf (LOG_VERBOSE, _("\
1969 Remote file no newer than local file %s -- not retrieving.\n"), quote (con->target));
1970                   dlthis = false;
1971                 }
1972               else if (eq_size)
1973                 {
1974                   /* Remote file is newer or sizes cannot be matched */
1975                   logprintf (LOG_VERBOSE, _("\
1976 Remote file is newer than local file %s -- retrieving.\n\n"),
1977                              quote (con->target));
1978                 }
1979               else
1980                 {
1981                   /* Sizes do not match */
1982                   logprintf (LOG_VERBOSE, _("\
1983 The sizes do not match (local %s) -- retrieving.\n\n"),
1984                              number_to_static_string (local_size));
1985                 }
1986             }
1987         }       /* opt.timestamping && f->type == FT_PLAINFILE */
1988       switch (f->type)
1989         {
1990         case FT_SYMLINK:
1991           /* If opt.retr_symlinks is defined, we treat symlinks as
1992              if they were normal files.  There is currently no way
1993              to distinguish whether they might be directories, and
1994              follow them.  */
1995           if (!opt.retr_symlinks)
1996             {
1997 #ifdef HAVE_SYMLINK
1998               if (!f->linkto)
1999                 logputs (LOG_NOTQUIET,
2000                          _("Invalid name of the symlink, skipping.\n"));
2001               else
2002                 {
2003                   struct_stat st;
2004                   /* Check whether we already have the correct
2005                      symbolic link.  */
2006                   int rc = lstat (con->target, &st);
2007                   if (rc == 0)
2008                     {
2009                       size_t len = strlen (f->linkto) + 1;
2010                       if (S_ISLNK (st.st_mode))
2011                         {
2012                           char *link_target = (char *)alloca (len);
2013                           size_t n = readlink (con->target, link_target, len);
2014                           if ((n == len - 1)
2015                               && (memcmp (link_target, f->linkto, n) == 0))
2016                             {
2017                               logprintf (LOG_VERBOSE, _("\
2018 Already have correct symlink %s -> %s\n\n"),
2019                                          quote (con->target),
2020                                          quote (f->linkto));
2021                               dlthis = false;
2022                               break;
2023                             }
2024                         }
2025                     }
2026                   logprintf (LOG_VERBOSE, _("Creating symlink %s -> %s\n"),
2027                              quote (con->target), quote (f->linkto));
2028                   /* Unlink before creating symlink!  */
2029                   unlink (con->target);
2030                   if (symlink (f->linkto, con->target) == -1)
2031                     logprintf (LOG_NOTQUIET, "symlink: %s\n", strerror (errno));
2032                   logputs (LOG_VERBOSE, "\n");
2033                 } /* have f->linkto */
2034 #else  /* not HAVE_SYMLINK */
2035               logprintf (LOG_NOTQUIET,
2036                          _("Symlinks not supported, skipping symlink %s.\n"),
2037                          quote (con->target));
2038 #endif /* not HAVE_SYMLINK */
2039             }
2040           else                /* opt.retr_symlinks */
2041             {
2042               if (dlthis)
2043                 err = ftp_loop_internal (u, f, con, NULL);
2044             } /* opt.retr_symlinks */
2045           break;
2046         case FT_DIRECTORY:
2047           if (!opt.recursive)
2048             logprintf (LOG_NOTQUIET, _("Skipping directory %s.\n"),
2049                        quote (f->name));
2050           break;
2051         case FT_PLAINFILE:
2052           /* Call the retrieve loop.  */
2053           if (dlthis)
2054             err = ftp_loop_internal (u, f, con, NULL);
2055           break;
2056         case FT_UNKNOWN:
2057           logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
2058                      quote (f->name));
2059           break;
2060         }       /* switch */
2061
2062
2063       /* 2004-12-15 SMS.
2064        * Set permissions _before_ setting the times, as setting the
2065        * permissions changes the modified-time, at least on VMS.
2066        * Also, use the opt.output_document name here, too, as
2067        * appropriate.  (Do the test once, and save the result.)
2068        */
2069
2070       set_local_file (&actual_target, con->target);
2071
2072       /* If downloading a plain file, and the user requested it, then
2073          set valid (non-zero) permissions. */
2074       if (dlthis && (actual_target != NULL) &&
2075        (f->type == FT_PLAINFILE) && opt.preserve_perm)
2076         {
2077           if (f->perms)
2078             chmod (actual_target, f->perms);
2079           else
2080             DEBUGP (("Unrecognized permissions for %s.\n", actual_target));
2081         }
2082
2083       /* Set the time-stamp information to the local file.  Symlinks
2084          are not to be stamped because it sets the stamp on the
2085          original.  :( */
2086       if (actual_target != NULL)
2087         {
2088           if (opt.useservertimestamps
2089               && !(f->type == FT_SYMLINK && !opt.retr_symlinks)
2090               && f->tstamp != -1
2091               && dlthis
2092               && file_exists_p (con->target))
2093             {
2094               touch (actual_target, f->tstamp);
2095             }
2096           else if (f->tstamp == -1)
2097             logprintf (LOG_NOTQUIET, _("%s: corrupt time-stamp.\n"),
2098                        actual_target);
2099         }
2100
2101       xfree (con->target);
2102       con->target = old_target;
2103
2104       url_set_file (u, ofile);
2105       xfree (ofile);
2106
2107       /* Break on fatals.  */
2108       if (err == QUOTEXC || err == HOSTERR || err == FWRITEERR
2109           || err == WARC_ERR || err == WARC_TMP_FOPENERR
2110           || err == WARC_TMP_FWRITEERR)
2111         break;
2112       con->cmd &= ~ (DO_CWD | DO_LOGIN);
2113       f = f->next;
2114     }
2115
2116   /* We do not want to call ftp_retrieve_dirs here */
2117   if (opt.recursive &&
2118       !(opt.reclevel != INFINITE_RECURSION && depth >= opt.reclevel))
2119     err = ftp_retrieve_dirs (u, orig, con);
2120   else if (opt.recursive)
2121     DEBUGP ((_("Will not retrieve dirs since depth is %d (max %d).\n"),
2122              depth, opt.reclevel));
2123   --depth;
2124   return err;
2125 }
2126
2127 /* Retrieve the directories given in a file list.  This function works
2128    by simply going through the linked list and calling
2129    ftp_retrieve_glob on each directory entry.  The function knows
2130    about excluded directories.  */
2131 static uerr_t
2132 ftp_retrieve_dirs (struct url *u, struct fileinfo *f, ccon *con)
2133 {
2134   char *container = NULL;
2135   int container_size = 0;
2136
2137   for (; f; f = f->next)
2138     {
2139       int size;
2140       char *odir, *newdir;
2141
2142       if (opt.quota && total_downloaded_bytes > opt.quota)
2143         break;
2144       if (f->type != FT_DIRECTORY)
2145         continue;
2146
2147       /* Allocate u->dir off stack, but reallocate only if a larger
2148          string is needed.  It's a pity there's no "realloca" for an
2149          item on the bottom of the stack.  */
2150       size = strlen (u->dir) + 1 + strlen (f->name) + 1;
2151       if (size > container_size)
2152         container = (char *)alloca (size);
2153       newdir = container;
2154
2155       odir = u->dir;
2156       if (*odir == '\0'
2157           || (*odir == '/' && *(odir + 1) == '\0'))
2158         /* If ODIR is empty or just "/", simply append f->name to
2159            ODIR.  (In the former case, to preserve u->dir being
2160            relative; in the latter case, to avoid double slash.)  */
2161         sprintf (newdir, "%s%s", odir, f->name);
2162       else
2163         /* Else, use a separator. */
2164         sprintf (newdir, "%s/%s", odir, f->name);
2165
2166       DEBUGP (("Composing new CWD relative to the initial directory.\n"));
2167       DEBUGP (("  odir = '%s'\n  f->name = '%s'\n  newdir = '%s'\n\n",
2168                odir, f->name, newdir));
2169       if (!accdir (newdir))
2170         {
2171           logprintf (LOG_VERBOSE, _("\
2172 Not descending to %s as it is excluded/not-included.\n"),
2173                      quote (newdir));
2174           continue;
2175         }
2176
2177       con->st &= ~DONE_CWD;
2178
2179       odir = xstrdup (u->dir);  /* because url_set_dir will free
2180                                    u->dir. */
2181       url_set_dir (u, newdir);
2182       ftp_retrieve_glob (u, con, GLOB_GETALL);
2183       url_set_dir (u, odir);
2184       xfree (odir);
2185
2186       /* Set the time-stamp?  */
2187     }
2188
2189   if (opt.quota && total_downloaded_bytes > opt.quota)
2190     return QUOTEXC;
2191   else
2192     return RETROK;
2193 }
2194
2195 /* Return true if S has a leading '/'  or contains '../' */
2196 static bool
2197 has_insecure_name_p (const char *s)
2198 {
2199   if (*s == '/')
2200     return true;
2201
2202   if (strstr (s, "../") != 0)
2203     return true;
2204
2205   return false;
2206 }
2207
2208 /* A near-top-level function to retrieve the files in a directory.
2209    The function calls ftp_get_listing, to get a linked list of files.
2210    Then it weeds out the file names that do not match the pattern.
2211    ftp_retrieve_list is called with this updated list as an argument.
2212
2213    If the argument ACTION is GLOB_GETONE, just download the file (but
2214    first get the listing, so that the time-stamp is heeded); if it's
2215    GLOB_GLOBALL, use globbing; if it's GLOB_GETALL, download the whole
2216    directory.  */
2217 static uerr_t
2218 ftp_retrieve_glob (struct url *u, ccon *con, int action)
2219 {
2220   struct fileinfo *f, *start;
2221   uerr_t res;
2222
2223   con->cmd |= LEAVE_PENDING;
2224
2225   res = ftp_get_listing (u, con, &start);
2226   if (res != RETROK)
2227     return res;
2228   /* First: weed out that do not conform the global rules given in
2229      opt.accepts and opt.rejects.  */
2230   if (opt.accepts || opt.rejects)
2231     {
2232       f = start;
2233       while (f)
2234         {
2235           if (f->type != FT_DIRECTORY && !acceptable (f->name))
2236             {
2237               logprintf (LOG_VERBOSE, _("Rejecting %s.\n"),
2238                          quote (f->name));
2239               f = delelement (f, &start);
2240             }
2241           else
2242             f = f->next;
2243         }
2244     }
2245   /* Remove all files with possible harmful names */
2246   f = start;
2247   while (f)
2248     {
2249       if (has_insecure_name_p (f->name))
2250         {
2251           logprintf (LOG_VERBOSE, _("Rejecting %s.\n"),
2252                      quote (f->name));
2253           f = delelement (f, &start);
2254         }
2255       else
2256         f = f->next;
2257     }
2258   /* Now weed out the files that do not match our globbing pattern.
2259      If we are dealing with a globbing pattern, that is.  */
2260   if (*u->file)
2261     {
2262       if (action == GLOB_GLOBALL)
2263         {
2264           int (*matcher) (const char *, const char *, int)
2265             = opt.ignore_case ? fnmatch_nocase : fnmatch;
2266           int matchres = 0;
2267
2268           f = start;
2269           while (f)
2270             {
2271               matchres = matcher (u->file, f->name, 0);
2272               if (matchres == -1)
2273                 {
2274                   logprintf (LOG_NOTQUIET, _("Error matching %s against %s: %s\n"),
2275                              u->file, quotearg_style (escape_quoting_style, f->name),
2276                              strerror (errno));
2277                   break;
2278                 }
2279               if (matchres == FNM_NOMATCH)
2280                 f = delelement (f, &start); /* delete the element from the list */
2281               else
2282                 f = f->next;        /* leave the element in the list */
2283             }
2284           if (matchres == -1)
2285             {
2286               freefileinfo (start);
2287               return RETRBADPATTERN;
2288             }
2289         }
2290       else if (action == GLOB_GETONE)
2291         {
2292 #ifdef __VMS
2293           /* 2009-09-09 SMS.
2294            * Odd-ball compiler ("HP C V7.3-009 on OpenVMS Alpha V7.3-2")
2295            * bug causes spurious %CC-E-BADCONDIT complaint with this
2296            * "?:" statement.  (Different linkage attributes for strcmp()
2297            * and strcasecmp().)  Converting to "if" changes the
2298            * complaint to %CC-W-PTRMISMATCH on "cmp = strcmp;".  Adding
2299            * the senseless type cast clears the complaint, and looks
2300            * harmless.
2301            */
2302           int (*cmp) (const char *, const char *)
2303             = opt.ignore_case ? strcasecmp : (int (*)())strcmp;
2304 #else /* def __VMS */
2305           int (*cmp) (const char *, const char *)
2306             = opt.ignore_case ? strcasecmp : strcmp;
2307 #endif /* def __VMS [else] */
2308           f = start;
2309           while (f)
2310             {
2311               if (0 != cmp(u->file, f->name))
2312                 f = delelement (f, &start);
2313               else
2314                 f = f->next;
2315             }
2316         }
2317     }
2318   if (start)
2319     {
2320       /* Just get everything.  */
2321       res = ftp_retrieve_list (u, start, con);
2322     }
2323   else
2324     {
2325       if (action == GLOB_GLOBALL)
2326         {
2327           /* No luck.  */
2328           /* #### This message SUCKS.  We should see what was the
2329              reason that nothing was retrieved.  */
2330           logprintf (LOG_VERBOSE, _("No matches on pattern %s.\n"),
2331                      quote (u->file));
2332         }
2333       else if (action == GLOB_GETONE) /* GLOB_GETONE or GLOB_GETALL */
2334         {
2335           /* Let's try retrieving it anyway.  */
2336           con->st |= ON_YOUR_OWN;
2337           res = ftp_loop_internal (u, NULL, con, NULL);
2338           return res;
2339         }
2340
2341       /* If action == GLOB_GETALL, and the file list is empty, there's
2342          no point in trying to download anything or in complaining about
2343          it.  (An empty directory should not cause complaints.)
2344       */
2345     }
2346   freefileinfo (start);
2347   if (opt.quota && total_downloaded_bytes > opt.quota)
2348     return QUOTEXC;
2349   else
2350     return res;
2351 }
2352
2353 /* The wrapper that calls an appropriate routine according to contents
2354    of URL.  Inherently, its capabilities are limited on what can be
2355    encoded into a URL.  */
2356 uerr_t
2357 ftp_loop (struct url *u, char **local_file, int *dt, struct url *proxy,
2358           bool recursive, bool glob)
2359 {
2360   ccon con;                     /* FTP connection */
2361   uerr_t res;
2362
2363   *dt = 0;
2364
2365   xzero (con);
2366
2367   con.csock = -1;
2368   con.st = ON_YOUR_OWN;
2369   con.rs = ST_UNIX;
2370   con.id = NULL;
2371   con.proxy = proxy;
2372
2373   /* If the file name is empty, the user probably wants a directory
2374      index.  We'll provide one, properly HTML-ized.  Unless
2375      opt.htmlify is 0, of course.  :-) */
2376   if (!*u->file && !recursive)
2377     {
2378       struct fileinfo *f;
2379       res = ftp_get_listing (u, &con, &f);
2380
2381       if (res == RETROK)
2382         {
2383           if (opt.htmlify && !opt.spider)
2384             {
2385               char *filename = (opt.output_document
2386                                 ? xstrdup (opt.output_document)
2387                                 : (con.target ? xstrdup (con.target)
2388                                    : url_file_name (u, NULL)));
2389               res = ftp_index (filename, u, f);
2390               if (res == FTPOK && opt.verbose)
2391                 {
2392                   if (!opt.output_document)
2393                     {
2394                       struct_stat st;
2395                       wgint sz;
2396                       if (stat (filename, &st) == 0)
2397                         sz = st.st_size;
2398                       else
2399                         sz = -1;
2400                       logprintf (LOG_NOTQUIET,
2401                                  _("Wrote HTML-ized index to %s [%s].\n"),
2402                                  quote (filename), number_to_static_string (sz));
2403                     }
2404                   else
2405                     logprintf (LOG_NOTQUIET,
2406                                _("Wrote HTML-ized index to %s.\n"),
2407                                quote (filename));
2408                 }
2409               xfree (filename);
2410             }
2411           freefileinfo (f);
2412         }
2413     }
2414   else
2415     {
2416       bool ispattern = false;
2417       if (glob)
2418         {
2419           /* Treat the URL as a pattern if the file name part of the
2420              URL path contains wildcards.  (Don't check for u->file
2421              because it is unescaped and therefore doesn't leave users
2422              the option to escape literal '*' as %2A.)  */
2423           char *file_part = strrchr (u->path, '/');
2424           if (!file_part)
2425             file_part = u->path;
2426           ispattern = has_wildcards_p (file_part);
2427         }
2428       if (ispattern || recursive || opt.timestamping || opt.preserve_perm)
2429         {
2430           /* ftp_retrieve_glob is a catch-all function that gets called
2431              if we need globbing, time-stamping, recursion or preserve
2432              permissions.  Its third argument is just what we really need.  */
2433           res = ftp_retrieve_glob (u, &con,
2434                                    ispattern ? GLOB_GLOBALL : GLOB_GETONE);
2435         }
2436       else
2437         res = ftp_loop_internal (u, NULL, &con, local_file);
2438     }
2439   if (res == FTPOK)
2440     res = RETROK;
2441   if (res == RETROK)
2442     *dt |= RETROKF;
2443   /* If a connection was left, quench it.  */
2444   if (con.csock != -1)
2445     fd_close (con.csock);
2446   xfree_null (con.id);
2447   con.id = NULL;
2448   xfree_null (con.target);
2449   con.target = NULL;
2450   return res;
2451 }
2452
2453 /* Delete an element from the fileinfo linked list.  Returns the
2454    address of the next element, or NULL if the list is exhausted.  It
2455    can modify the start of the list.  */
2456 static struct fileinfo *
2457 delelement (struct fileinfo *f, struct fileinfo **start)
2458 {
2459   struct fileinfo *prev = f->prev;
2460   struct fileinfo *next = f->next;
2461
2462   xfree (f->name);
2463   xfree_null (f->linkto);
2464   xfree (f);
2465
2466   if (next)
2467     next->prev = prev;
2468   if (prev)
2469     prev->next = next;
2470   else
2471     *start = next;
2472   return next;
2473 }
2474
2475 /* Free the fileinfo linked list of files.  */
2476 static void
2477 freefileinfo (struct fileinfo *f)
2478 {
2479   while (f)
2480     {
2481       struct fileinfo *next = f->next;
2482       xfree (f->name);
2483       if (f->linkto)
2484         xfree (f->linkto);
2485       xfree (f);
2486       f = next;
2487     }
2488 }