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