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