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