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