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