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