]> sjero.net Git - wget/blob - src/ftp.c
Automated merge with file:/home/micah/devel/wget/fix-double-gets
[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 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 In addition, as a special exception, the Free Software Foundation
21 gives permission to link the code of its release of Wget with the
22 OpenSSL project's "OpenSSL" library (or with modified versions of it
23 that use the same license as the "OpenSSL" library), and distribute
24 the linked executables.  You must obey the GNU General Public License
25 in all respects for all of the code used other than "OpenSSL".  If you
26 modify this file, you may extend this exception to your version of the
27 file, but you are not obligated to do so.  If you do not wish to do
28 so, delete this exception statement from your version.  */
29
30 #include <config.h>
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #ifdef HAVE_UNISTD_H
36 # include <unistd.h>
37 #endif
38 #include <assert.h>
39 #include <errno.h>
40 #include <time.h>
41
42 #include "wget.h"
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 && ISSPACE (*s))
92         ++s;
93       if (!*s)
94         return 0;
95       if (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                    && 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)
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 (opt.always_rest
1145           && stat (locf, &st) == 0
1146           && S_ISREG (st.st_mode))
1147         /* When -c is used, continue from on-disk size.  (Can't use
1148            hstat.len even if count>1 because we don't want a failed
1149            first attempt to clobber existing data.)  */
1150         restval = st.st_size;
1151       else if (count > 1)
1152         restval = len;          /* start where the previous run left off */
1153       else
1154         restval = 0;
1155
1156       /* Get the current time string.  */
1157       tms = datetime_str (time (NULL));
1158       /* Print fetch message, if opt.verbose.  */
1159       if (opt.verbose)
1160         {
1161           char *hurl = url_string (u, URL_AUTH_HIDE_PASSWD);
1162           char tmp[256];
1163           strcpy (tmp, "        ");
1164           if (count > 1)
1165             sprintf (tmp, _("(try:%2d)"), count);
1166           logprintf (LOG_VERBOSE, "--%s--  %s\n  %s => `%s'\n",
1167                      tms, hurl, tmp, locf);
1168 #ifdef WINDOWS
1169           ws_changetitle (hurl);
1170 #endif
1171           xfree (hurl);
1172         }
1173       /* Send getftp the proper length, if fileinfo was provided.  */
1174       if (f)
1175         len = f->size;
1176       else
1177         len = 0;
1178       err = getftp (u, &len, restval, con);
1179
1180       if (con->csock == -1)
1181         con->st &= ~DONE_CWD;
1182       else
1183         con->st |= DONE_CWD;
1184
1185       switch (err)
1186         {
1187         case HOSTERR: case CONIMPOSSIBLE: case FWRITEERR: case FOPENERR:
1188         case FTPNSFOD: case FTPLOGINC: case FTPNOPASV: case CONTNOTSUPPORTED:
1189           /* Fatal errors, give up.  */
1190           return err;
1191         case CONSOCKERR: case CONERROR: case FTPSRVERR: case FTPRERR:
1192         case WRITEFAILED: case FTPUNKNOWNTYPE: case FTPSYSERR:
1193         case FTPPORTERR: case FTPLOGREFUSED: case FTPINVPASV:
1194         case FOPEN_EXCL_ERR:
1195           printwhat (count, opt.ntry);
1196           /* non-fatal errors */
1197           if (err == FOPEN_EXCL_ERR)
1198             {
1199               /* Re-determine the file name. */
1200               xfree_null (con->target);
1201               con->target = url_file_name (u);
1202               locf = con->target;
1203             }
1204           continue;
1205         case FTPRETRINT:
1206           /* If the control connection was closed, the retrieval
1207              will be considered OK if f->size == len.  */
1208           if (!f || len != f->size)
1209             {
1210               printwhat (count, opt.ntry);
1211               continue;
1212             }
1213           break;
1214         case RETRFINISHED:
1215           /* Great!  */
1216           break;
1217         default:
1218           /* Not as great.  */
1219           abort ();
1220         }
1221       tms = datetime_str (time (NULL));
1222       if (!opt.spider)
1223         tmrate = retr_rate (len - restval, con->dltime);
1224
1225       /* If we get out of the switch above without continue'ing, we've
1226          successfully downloaded a file.  Remember this fact. */
1227       downloaded_file (FILE_DOWNLOADED_NORMALLY, locf);
1228
1229       if (con->st & ON_YOUR_OWN)
1230         {
1231           fd_close (con->csock);
1232           con->csock = -1;
1233         }
1234       if (!opt.spider)
1235         logprintf (LOG_VERBOSE, _("%s (%s) - `%s' saved [%s]\n\n"),
1236                    tms, tmrate, locf, number_to_static_string (len));
1237       if (!opt.verbose && !opt.quiet)
1238         {
1239           /* Need to hide the password from the URL.  The `if' is here
1240              so that we don't do the needless allocation every
1241              time. */
1242           char *hurl = url_string (u, URL_AUTH_HIDE_PASSWD);
1243           logprintf (LOG_NONVERBOSE, "%s URL: %s [%s] -> \"%s\" [%d]\n",
1244                      tms, hurl, number_to_static_string (len), locf, count);
1245           xfree (hurl);
1246         }
1247
1248       if ((con->cmd & DO_LIST))
1249         /* This is a directory listing file. */
1250         {
1251           if (!opt.remove_listing)
1252             /* --dont-remove-listing was specified, so do count this towards the
1253                number of bytes and files downloaded. */
1254             {
1255               total_downloaded_bytes += len;
1256               opt.numurls++;
1257             }
1258
1259           /* Deletion of listing files is not controlled by --delete-after, but
1260              by the more specific option --dont-remove-listing, and the code
1261              to do this deletion is in another function. */
1262         }
1263       else if (!opt.spider)
1264         /* This is not a directory listing file. */
1265         {
1266           /* Unlike directory listing files, don't pretend normal files weren't
1267              downloaded if they're going to be deleted.  People seeding proxies,
1268              for instance, may want to know how many bytes and files they've
1269              downloaded through it. */
1270           total_downloaded_bytes += len;
1271           opt.numurls++;
1272
1273           if (opt.delete_after)
1274             {
1275               DEBUGP (("\
1276 Removing file due to --delete-after in ftp_loop_internal():\n"));
1277               logprintf (LOG_VERBOSE, _("Removing %s.\n"), locf);
1278               if (unlink (locf))
1279                 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1280             }
1281         }
1282
1283       /* Restore the original leave-pendingness.  */
1284       if (orig_lp)
1285         con->cmd |= LEAVE_PENDING;
1286       else
1287         con->cmd &= ~LEAVE_PENDING;
1288       return RETROK;
1289     } while (!opt.ntry || (count < opt.ntry));
1290
1291   if (con->csock != -1 && (con->st & ON_YOUR_OWN))
1292     {
1293       fd_close (con->csock);
1294       con->csock = -1;
1295     }
1296   return TRYLIMEXC;
1297 }
1298
1299 /* Return the directory listing in a reusable format.  The directory
1300    is specifed in u->dir.  */
1301 static uerr_t
1302 ftp_get_listing (struct url *u, ccon *con, struct fileinfo **f)
1303 {
1304   uerr_t err;
1305   char *uf;                     /* url file name */
1306   char *lf;                     /* list file name */
1307   char *old_target = con->target;
1308
1309   con->st &= ~ON_YOUR_OWN;
1310   con->cmd |= (DO_LIST | LEAVE_PENDING);
1311   con->cmd &= ~DO_RETR;
1312
1313   /* Find the listing file name.  We do it by taking the file name of
1314      the URL and replacing the last component with the listing file
1315      name.  */
1316   uf = url_file_name (u);
1317   lf = file_merge (uf, LIST_FILENAME);
1318   xfree (uf);
1319   DEBUGP ((_("Using `%s' as listing tmp file.\n"), lf));
1320
1321   con->target = lf;
1322   err = ftp_loop_internal (u, NULL, con);
1323   con->target = old_target;
1324
1325   if (err == RETROK)
1326     *f = ftp_parse_ls (lf, con->rs);
1327   else
1328     *f = NULL;
1329   if (opt.remove_listing)
1330     {
1331       if (unlink (lf))
1332         logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1333       else
1334         logprintf (LOG_VERBOSE, _("Removed `%s'.\n"), lf);
1335     }
1336   xfree (lf);
1337   con->cmd &= ~DO_LIST;
1338   return err;
1339 }
1340
1341 static uerr_t ftp_retrieve_dirs (struct url *, struct fileinfo *, ccon *);
1342 static uerr_t ftp_retrieve_glob (struct url *, ccon *, int);
1343 static struct fileinfo *delelement (struct fileinfo *, struct fileinfo **);
1344 static void freefileinfo (struct fileinfo *f);
1345
1346 /* Retrieve a list of files given in struct fileinfo linked list.  If
1347    a file is a symbolic link, do not retrieve it, but rather try to
1348    set up a similar link on the local disk, if the symlinks are
1349    supported.
1350
1351    If opt.recursive is set, after all files have been retrieved,
1352    ftp_retrieve_dirs will be called to retrieve the directories.  */
1353 static uerr_t
1354 ftp_retrieve_list (struct url *u, struct fileinfo *f, ccon *con)
1355 {
1356   static int depth = 0;
1357   uerr_t err;
1358   struct fileinfo *orig;
1359   wgint local_size;
1360   time_t tml;
1361   bool dlthis;
1362
1363   /* Increase the depth.  */
1364   ++depth;
1365   if (opt.reclevel != INFINITE_RECURSION && depth > opt.reclevel)
1366     {
1367       DEBUGP ((_("Recursion depth %d exceeded max. depth %d.\n"),
1368                depth, opt.reclevel));
1369       --depth;
1370       return RECLEVELEXC;
1371     }
1372
1373   assert (f != NULL);
1374   orig = f;
1375
1376   con->st &= ~ON_YOUR_OWN;
1377   if (!(con->st & DONE_CWD))
1378     con->cmd |= DO_CWD;
1379   else
1380     con->cmd &= ~DO_CWD;
1381   con->cmd |= (DO_RETR | LEAVE_PENDING);
1382
1383   if (con->csock < 0)
1384     con->cmd |= DO_LOGIN;
1385   else
1386     con->cmd &= ~DO_LOGIN;
1387
1388   err = RETROK;                 /* in case it's not used */
1389
1390   while (f)
1391     {
1392       char *old_target, *ofile;
1393
1394       if (opt.quota && total_downloaded_bytes > opt.quota)
1395         {
1396           --depth;
1397           return QUOTEXC;
1398         }
1399       old_target = con->target;
1400
1401       ofile = xstrdup (u->file);
1402       url_set_file (u, f->name);
1403
1404       con->target = url_file_name (u);
1405       err = RETROK;
1406
1407       dlthis = true;
1408       if (opt.timestamping && f->type == FT_PLAINFILE)
1409         {
1410           struct_stat st;
1411           /* If conversion of HTML files retrieved via FTP is ever implemented,
1412              we'll need to stat() <file>.orig here when -K has been specified.
1413              I'm not implementing it now since files on an FTP server are much
1414              more likely than files on an HTTP server to legitimately have a
1415              .orig suffix. */
1416           if (!stat (con->target, &st))
1417             {
1418               bool eq_size;
1419               bool cor_val;
1420               /* Else, get it from the file.  */
1421               local_size = st.st_size;
1422               tml = st.st_mtime;
1423 #ifdef WINDOWS
1424               /* Modification time granularity is 2 seconds for Windows, so
1425                  increase local time by 1 second for later comparison. */
1426               tml++;
1427 #endif
1428               /* Compare file sizes only for servers that tell us correct
1429                  values. Assume sizes being equal for servers that lie
1430                  about file size.  */
1431               cor_val = (con->rs == ST_UNIX || con->rs == ST_WINNT);
1432               eq_size = cor_val ? (local_size == f->size) : true;
1433               if (f->tstamp <= tml && eq_size)
1434                 {
1435                   /* Remote file is older, file sizes can be compared and
1436                      are both equal. */
1437                   logprintf (LOG_VERBOSE, _("\
1438 Remote file no newer than local file `%s' -- not retrieving.\n"), con->target);
1439                   dlthis = false;
1440                 }
1441               else if (eq_size)
1442                 {
1443                   /* Remote file is newer or sizes cannot be matched */
1444                   logprintf (LOG_VERBOSE, _("\
1445 Remote file is newer than local file `%s' -- retrieving.\n\n"),
1446                              con->target);
1447                 }
1448               else
1449                 {
1450                   /* Sizes do not match */
1451                   logprintf (LOG_VERBOSE, _("\
1452 The sizes do not match (local %s) -- retrieving.\n\n"),
1453                              number_to_static_string (local_size));
1454                 }
1455             }
1456         }       /* opt.timestamping && f->type == FT_PLAINFILE */
1457       switch (f->type)
1458         {
1459         case FT_SYMLINK:
1460           /* If opt.retr_symlinks is defined, we treat symlinks as
1461              if they were normal files.  There is currently no way
1462              to distinguish whether they might be directories, and
1463              follow them.  */
1464           if (!opt.retr_symlinks)
1465             {
1466 #ifdef HAVE_SYMLINK
1467               if (!f->linkto)
1468                 logputs (LOG_NOTQUIET,
1469                          _("Invalid name of the symlink, skipping.\n"));
1470               else
1471                 {
1472                   struct_stat st;
1473                   /* Check whether we already have the correct
1474                      symbolic link.  */
1475                   int rc = lstat (con->target, &st);
1476                   if (rc == 0)
1477                     {
1478                       size_t len = strlen (f->linkto) + 1;
1479                       if (S_ISLNK (st.st_mode))
1480                         {
1481                           char *link_target = (char *)alloca (len);
1482                           size_t n = readlink (con->target, link_target, len);
1483                           if ((n == len - 1)
1484                               && (memcmp (link_target, f->linkto, n) == 0))
1485                             {
1486                               logprintf (LOG_VERBOSE, _("\
1487 Already have correct symlink %s -> %s\n\n"),
1488                                          con->target, escnonprint (f->linkto));
1489                               dlthis = false;
1490                               break;
1491                             }
1492                         }
1493                     }
1494                   logprintf (LOG_VERBOSE, _("Creating symlink %s -> %s\n"),
1495                              con->target, escnonprint (f->linkto));
1496                   /* Unlink before creating symlink!  */
1497                   unlink (con->target);
1498                   if (symlink (f->linkto, con->target) == -1)
1499                     logprintf (LOG_NOTQUIET, "symlink: %s\n", strerror (errno));
1500                   logputs (LOG_VERBOSE, "\n");
1501                 } /* have f->linkto */
1502 #else  /* not HAVE_SYMLINK */
1503               logprintf (LOG_NOTQUIET,
1504                          _("Symlinks not supported, skipping symlink `%s'.\n"),
1505                          con->target);
1506 #endif /* not HAVE_SYMLINK */
1507             }
1508           else                /* opt.retr_symlinks */
1509             {
1510               if (dlthis)
1511                 err = ftp_loop_internal (u, f, con);
1512             } /* opt.retr_symlinks */
1513           break;
1514         case FT_DIRECTORY:
1515           if (!opt.recursive)
1516             logprintf (LOG_NOTQUIET, _("Skipping directory `%s'.\n"),
1517                        escnonprint (f->name));
1518           break;
1519         case FT_PLAINFILE:
1520           /* Call the retrieve loop.  */
1521           if (dlthis)
1522             err = ftp_loop_internal (u, f, con);
1523           break;
1524         case FT_UNKNOWN:
1525           logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
1526                      escnonprint (f->name));
1527           break;
1528         }       /* switch */
1529
1530       /* Set the time-stamp information to the local file.  Symlinks
1531          are not to be stamped because it sets the stamp on the
1532          original.  :( */
1533       if (!(f->type == FT_SYMLINK && !opt.retr_symlinks)
1534           && f->tstamp != -1
1535           && dlthis
1536           && file_exists_p (con->target))
1537         {
1538           /* #### This code repeats in http.c and ftp.c.  Move it to a
1539              function!  */
1540           const char *fl = NULL;
1541           if (opt.output_document)
1542             {
1543               if (output_stream_regular)
1544                 fl = opt.output_document;
1545             }
1546           else
1547             fl = con->target;
1548           if (fl)
1549             touch (fl, f->tstamp);
1550         }
1551       else if (f->tstamp == -1)
1552         logprintf (LOG_NOTQUIET, _("%s: corrupt time-stamp.\n"), con->target);
1553
1554       if (f->perms && f->type == FT_PLAINFILE && dlthis)
1555         {
1556           if (opt.preserve_perm)
1557             chmod (con->target, f->perms);
1558         }
1559       else
1560         DEBUGP (("Unrecognized permissions for %s.\n", con->target));
1561
1562       xfree (con->target);
1563       con->target = old_target;
1564
1565       url_set_file (u, ofile);
1566       xfree (ofile);
1567
1568       /* Break on fatals.  */
1569       if (err == QUOTEXC || err == HOSTERR || err == FWRITEERR)
1570         break;
1571       con->cmd &= ~ (DO_CWD | DO_LOGIN);
1572       f = f->next;
1573     }
1574
1575   /* We do not want to call ftp_retrieve_dirs here */
1576   if (opt.recursive &&
1577       !(opt.reclevel != INFINITE_RECURSION && depth >= opt.reclevel))
1578     err = ftp_retrieve_dirs (u, orig, con);
1579   else if (opt.recursive)
1580     DEBUGP ((_("Will not retrieve dirs since depth is %d (max %d).\n"),
1581              depth, opt.reclevel));
1582   --depth;
1583   return err;
1584 }
1585
1586 /* Retrieve the directories given in a file list.  This function works
1587    by simply going through the linked list and calling
1588    ftp_retrieve_glob on each directory entry.  The function knows
1589    about excluded directories.  */
1590 static uerr_t
1591 ftp_retrieve_dirs (struct url *u, struct fileinfo *f, ccon *con)
1592 {
1593   char *container = NULL;
1594   int container_size = 0;
1595
1596   for (; f; f = f->next)
1597     {
1598       int size;
1599       char *odir, *newdir;
1600
1601       if (opt.quota && total_downloaded_bytes > opt.quota)
1602         break;
1603       if (f->type != FT_DIRECTORY)
1604         continue;
1605
1606       /* Allocate u->dir off stack, but reallocate only if a larger
1607          string is needed.  It's a pity there's no "realloca" for an
1608          item on the bottom of the stack.  */
1609       size = strlen (u->dir) + 1 + strlen (f->name) + 1;
1610       if (size > container_size)
1611         container = (char *)alloca (size);
1612       newdir = container;
1613
1614       odir = u->dir;
1615       if (*odir == '\0'
1616           || (*odir == '/' && *(odir + 1) == '\0'))
1617         /* If ODIR is empty or just "/", simply append f->name to
1618            ODIR.  (In the former case, to preserve u->dir being
1619            relative; in the latter case, to avoid double slash.)  */
1620         sprintf (newdir, "%s%s", odir, f->name);
1621       else
1622         /* Else, use a separator. */
1623         sprintf (newdir, "%s/%s", odir, f->name);
1624
1625       DEBUGP (("Composing new CWD relative to the initial directory.\n"));
1626       DEBUGP (("  odir = '%s'\n  f->name = '%s'\n  newdir = '%s'\n\n",
1627                odir, f->name, newdir));
1628       if (!accdir (newdir))
1629         {
1630           logprintf (LOG_VERBOSE, _("\
1631 Not descending to `%s' as it is excluded/not-included.\n"),
1632                      escnonprint (newdir));
1633           continue;
1634         }
1635
1636       con->st &= ~DONE_CWD;
1637
1638       odir = xstrdup (u->dir);  /* because url_set_dir will free
1639                                    u->dir. */
1640       url_set_dir (u, newdir);
1641       ftp_retrieve_glob (u, con, GLOB_GETALL);
1642       url_set_dir (u, odir);
1643       xfree (odir);
1644
1645       /* Set the time-stamp?  */
1646     }
1647
1648   if (opt.quota && total_downloaded_bytes > opt.quota)
1649     return QUOTEXC;
1650   else
1651     return RETROK;
1652 }
1653
1654 /* Return true if S has a leading '/'  or contains '../' */
1655 static bool
1656 has_insecure_name_p (const char *s)
1657 {
1658   if (*s == '/')
1659     return true;
1660
1661   if (strstr (s, "../") != 0)
1662     return true;
1663
1664   return false;
1665 }
1666
1667 /* A near-top-level function to retrieve the files in a directory.
1668    The function calls ftp_get_listing, to get a linked list of files.
1669    Then it weeds out the file names that do not match the pattern.
1670    ftp_retrieve_list is called with this updated list as an argument.
1671
1672    If the argument ACTION is GLOB_GETONE, just download the file (but
1673    first get the listing, so that the time-stamp is heeded); if it's
1674    GLOB_GLOBALL, use globbing; if it's GLOB_GETALL, download the whole
1675    directory.  */
1676 static uerr_t
1677 ftp_retrieve_glob (struct url *u, ccon *con, int action)
1678 {
1679   struct fileinfo *f, *start;
1680   uerr_t res;
1681
1682   con->cmd |= LEAVE_PENDING;
1683
1684   res = ftp_get_listing (u, con, &start);
1685   if (res != RETROK)
1686     return res;
1687   /* First: weed out that do not conform the global rules given in
1688      opt.accepts and opt.rejects.  */
1689   if (opt.accepts || opt.rejects)
1690     {
1691       f = start;
1692       while (f)
1693         {
1694           if (f->type != FT_DIRECTORY && !acceptable (f->name))
1695             {
1696               logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"),
1697                          escnonprint (f->name));
1698               f = delelement (f, &start);
1699             }
1700           else
1701             f = f->next;
1702         }
1703     }
1704   /* Remove all files with possible harmful names */
1705   f = start;
1706   while (f)
1707     {
1708       if (has_insecure_name_p (f->name))
1709         {
1710           logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"),
1711                      escnonprint (f->name));
1712           f = delelement (f, &start);
1713         }
1714       else
1715         f = f->next;
1716     }
1717   /* Now weed out the files that do not match our globbing pattern.
1718      If we are dealing with a globbing pattern, that is.  */
1719   if (*u->file && (action == GLOB_GLOBALL || action == GLOB_GETONE))
1720     {
1721       int (*matcher) (const char *, const char *, int)
1722         = opt.ignore_case ? fnmatch_nocase : fnmatch;
1723       int matchres = 0;
1724
1725       f = start;
1726       while (f)
1727         {
1728           matchres = matcher (u->file, f->name, 0);
1729           if (matchres == -1)
1730             {
1731               logprintf (LOG_NOTQUIET, "%s: %s\n", con->target,
1732                          strerror (errno));
1733               break;
1734             }
1735           if (matchres == FNM_NOMATCH)
1736             f = delelement (f, &start); /* delete the element from the list */
1737           else
1738             f = f->next;        /* leave the element in the list */
1739         }
1740       if (matchres == -1)
1741         {
1742           freefileinfo (start);
1743           return RETRBADPATTERN;
1744         }
1745     }
1746   if (start)
1747     {
1748       /* Just get everything.  */
1749       ftp_retrieve_list (u, start, con);
1750     }
1751   else if (!start)
1752     {
1753       if (action == GLOB_GLOBALL)
1754         {
1755           /* No luck.  */
1756           /* #### This message SUCKS.  We should see what was the
1757              reason that nothing was retrieved.  */
1758           logprintf (LOG_VERBOSE, _("No matches on pattern `%s'.\n"),
1759                      escnonprint (u->file));
1760         }
1761       else /* GLOB_GETONE or GLOB_GETALL */
1762         {
1763           /* Let's try retrieving it anyway.  */
1764           con->st |= ON_YOUR_OWN;
1765           res = ftp_loop_internal (u, NULL, con);
1766           return res;
1767         }
1768     }
1769   freefileinfo (start);
1770   if (opt.quota && total_downloaded_bytes > opt.quota)
1771     return QUOTEXC;
1772   else
1773     /* #### Should we return `res' here?  */
1774     return RETROK;
1775 }
1776
1777 /* The wrapper that calls an appropriate routine according to contents
1778    of URL.  Inherently, its capabilities are limited on what can be
1779    encoded into a URL.  */
1780 uerr_t
1781 ftp_loop (struct url *u, int *dt, struct url *proxy, bool recursive, bool glob)
1782 {
1783   ccon con;                     /* FTP connection */
1784   uerr_t res;
1785
1786   *dt = 0;
1787
1788   xzero (con);
1789
1790   con.csock = -1;
1791   con.st = ON_YOUR_OWN;
1792   con.rs = ST_UNIX;
1793   con.id = NULL;
1794   con.proxy = proxy;
1795
1796   /* If the file name is empty, the user probably wants a directory
1797      index.  We'll provide one, properly HTML-ized.  Unless
1798      opt.htmlify is 0, of course.  :-) */
1799   if (!*u->file && !recursive)
1800     {
1801       struct fileinfo *f;
1802       res = ftp_get_listing (u, &con, &f);
1803
1804       if (res == RETROK)
1805         {
1806           if (opt.htmlify && !opt.spider)
1807             {
1808               char *filename = (opt.output_document
1809                                 ? xstrdup (opt.output_document)
1810                                 : (con.target ? xstrdup (con.target)
1811                                    : url_file_name (u)));
1812               res = ftp_index (filename, u, f);
1813               if (res == FTPOK && opt.verbose)
1814                 {
1815                   if (!opt.output_document)
1816                     {
1817                       struct_stat st;
1818                       wgint sz;
1819                       if (stat (filename, &st) == 0)
1820                         sz = st.st_size;
1821                       else
1822                         sz = -1;
1823                       logprintf (LOG_NOTQUIET,
1824                                  _("Wrote HTML-ized index to `%s' [%s].\n"),
1825                                  filename, number_to_static_string (sz));
1826                     }
1827                   else
1828                     logprintf (LOG_NOTQUIET,
1829                                _("Wrote HTML-ized index to `%s'.\n"),
1830                                filename);
1831                 }
1832               xfree (filename);
1833             }
1834           freefileinfo (f);
1835         }
1836     }
1837   else
1838     {
1839       bool ispattern = false;
1840       if (glob)
1841         {
1842           /* Treat the URL as a pattern if the file name part of the
1843              URL path contains wildcards.  (Don't check for u->file
1844              because it is unescaped and therefore doesn't leave users
1845              the option to escape literal '*' as %2A.)  */
1846           char *file_part = strrchr (u->path, '/');
1847           if (!file_part)
1848             file_part = u->path;
1849           ispattern = has_wildcards_p (file_part);
1850         }
1851       if (ispattern || recursive || opt.timestamping)
1852         {
1853           /* ftp_retrieve_glob is a catch-all function that gets called
1854              if we need globbing, time-stamping or recursion.  Its
1855              third argument is just what we really need.  */
1856           res = ftp_retrieve_glob (u, &con,
1857                                    ispattern ? GLOB_GLOBALL : GLOB_GETONE);
1858         }
1859       else
1860         res = ftp_loop_internal (u, NULL, &con);
1861     }
1862   if (res == FTPOK)
1863     res = RETROK;
1864   if (res == RETROK)
1865     *dt |= RETROKF;
1866   /* If a connection was left, quench it.  */
1867   if (con.csock != -1)
1868     fd_close (con.csock);
1869   xfree_null (con.id);
1870   con.id = NULL;
1871   xfree_null (con.target);
1872   con.target = NULL;
1873   return res;
1874 }
1875
1876 /* Delete an element from the fileinfo linked list.  Returns the
1877    address of the next element, or NULL if the list is exhausted.  It
1878    can modify the start of the list.  */
1879 static struct fileinfo *
1880 delelement (struct fileinfo *f, struct fileinfo **start)
1881 {
1882   struct fileinfo *prev = f->prev;
1883   struct fileinfo *next = f->next;
1884
1885   xfree (f->name);
1886   xfree_null (f->linkto);
1887   xfree (f);
1888
1889   if (next)
1890     next->prev = prev;
1891   if (prev)
1892     prev->next = next;
1893   else
1894     *start = next;
1895   return next;
1896 }
1897
1898 /* Free the fileinfo linked list of files.  */
1899 static void
1900 freefileinfo (struct fileinfo *f)
1901 {
1902   while (f)
1903     {
1904       struct fileinfo *next = f->next;
1905       xfree (f->name);
1906       if (f->linkto)
1907         xfree (f->linkto);
1908       xfree (f);
1909       f = next;
1910     }
1911 }