]> sjero.net Git - wget/blob - src/ftp.c
[svn] --delete-after wasn't implemented for files retrieved by FTP or corresponding to
[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   /* If no transmission was required, then everything is OK.  */
652   if (!(cmd & (DO_LIST | DO_RETR)))
653     return RETRFINISHED;
654
655   if (!passive_mode_open)  /* we are not using pasive mode so we need
656                               to accept */
657     {
658       /* Open the data transmission socket by calling acceptport().  */
659       err = acceptport (&dtsock);
660       /* Possible errors: ACCEPTERR.  */
661       if (err == ACCEPTERR)
662         {
663           logprintf (LOG_NOTQUIET, "accept: %s\n", strerror (errno));
664           return err;
665         }
666     }
667
668   /* Open the file -- if opt.dfp is set, use it instead.  */
669   if (!opt.dfp || con->cmd & DO_LIST)
670     {
671       mkalldirs (u->local);
672       if (opt.backups)
673         rotate_backups (u->local);
674       /* #### Is this correct? */
675       chmod (u->local, 0600);
676
677       fp = fopen (u->local, restval ? "ab" : "wb");
678       if (!fp)
679         {
680           logprintf (LOG_NOTQUIET, "%s: %s\n", u->local, strerror (errno));
681           CLOSE (csock);
682           rbuf_uninitialize (&con->rbuf);
683           closeport (dtsock);
684           return FOPENERR;
685         }
686     }
687   else
688     fp = opt.dfp;
689   
690   /* Some FTP servers return the total length of file after REST command,
691      others just return the remaining size. */  
692   if (*len && restval && expected_bytes
693       && (expected_bytes == *len - restval))
694   {
695     DEBUGP (("Lying FTP server found, adjusting.\n"));
696     expected_bytes = *len;
697   }
698
699   if (*len)
700     {
701       logprintf (LOG_VERBOSE, _("Length: %s"), legible (*len));
702       if (restval)
703         logprintf (LOG_VERBOSE, _(" [%s to go]"), legible (*len - restval));
704       logputs (LOG_VERBOSE, "\n");
705     }
706   else if (expected_bytes)
707     {
708       logprintf (LOG_VERBOSE, _("Length: %s"), legible (expected_bytes));
709       if (restval)
710         logprintf (LOG_VERBOSE, _(" [%s to go]"),
711                    legible (expected_bytes - restval));
712       logputs (LOG_VERBOSE, _(" (unauthoritative)\n"));
713     }
714   reset_timer ();
715   /* Get the contents of the document.  */
716   res = get_contents (dtsock, fp, len, restval, expected_bytes, &con->rbuf);
717   con->dltime = elapsed_time ();
718   tms = time_str (NULL);
719   tmrate = rate (*len - restval, con->dltime);
720   /* Close data connection socket.  */
721   closeport (dtsock);
722   /* Close the local file.  */
723   {
724     /* Close or flush the file.  We have to be careful to check for
725        error here.  Checking the result of fwrite() is not enough --
726        errors could go unnoticed!  */
727     int flush_res;
728     if (!opt.dfp || con->cmd & DO_LIST)
729       flush_res = fclose (fp);
730     else
731       flush_res = fflush (fp);
732     if (flush_res == EOF)
733       res = -2;
734   }
735   /* If get_contents couldn't write to fp, bail out.  */
736   if (res == -2)
737     {
738       logprintf (LOG_NOTQUIET, _("%s: %s, closing control connection.\n"),
739                  u->local, strerror (errno));
740       CLOSE (csock);
741       rbuf_uninitialize (&con->rbuf);
742       return FWRITEERR;
743     }
744   else if (res == -1)
745     {
746       logprintf (LOG_NOTQUIET, _("%s (%s) - Data connection: %s; "),
747                  tms, tmrate, strerror (errno));
748       if (opt.server_response)
749         logputs (LOG_ALWAYS, "\n");
750     }
751
752   /* Get the server to tell us if everything is retrieved.  */
753   err = ftp_response (&con->rbuf, &respline);
754   /* ...and empty the buffer.  */
755   rbuf_discard (&con->rbuf);
756   if (err != FTPOK)
757     {
758       free (respline);
759       /* The control connection is decidedly closed.  Print the time
760          only if it hasn't already been printed.  */
761       if (res != -1)
762         logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
763       logputs (LOG_NOTQUIET, _("Control connection closed.\n"));
764       /* If there is an error on the control connection, close it, but
765          return FTPRETRINT, since there is a possibility that the
766          whole file was retrieved nevertheless (but that is for
767          ftp_loop_internal to decide).  */
768       CLOSE (csock);
769       rbuf_uninitialize (&con->rbuf);
770       return FTPRETRINT;
771     } /* err != FTPOK */
772   /* If retrieval failed for any reason, return FTPRETRINT, but do not
773      close socket, since the control connection is still alive.  If
774      there is something wrong with the control connection, it will
775      become apparent later.  */
776   if (*respline != '2')
777     {
778       free (respline);
779       if (res != -1)
780         logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
781       logputs (LOG_NOTQUIET, _("Data transfer aborted.\n"));
782       return FTPRETRINT;
783     }
784   free (respline);
785
786   if (res == -1)
787     {
788       /* What now?  The data connection was erroneous, whereas the
789          response says everything is OK.  We shall play it safe.  */
790       return FTPRETRINT;
791     }
792
793   if (!(cmd & LEAVE_PENDING))
794     {
795       /* I should probably send 'QUIT' and check for a reply, but this
796          is faster.  #### Is it OK, though?  */
797       CLOSE (csock);
798       rbuf_uninitialize (&con->rbuf);
799     }
800   /* If it was a listing, and opt.server_response is true,
801      print it out.  */
802   if (opt.server_response && (con->cmd & DO_LIST))
803     {
804       mkalldirs (u->local);
805       fp = fopen (u->local, "r");
806       if (!fp)
807         logprintf (LOG_ALWAYS, "%s: %s\n", u->local, strerror (errno));
808       else
809         {
810           char *line;
811           /* The lines are being read with read_whole_line because of
812              no-buffering on opt.lfile.  */
813           while ((line = read_whole_line (fp)))
814             {
815               logprintf (LOG_ALWAYS, "%s\n", line);
816               free (line);
817             }
818           fclose (fp);
819         }
820     } /* con->cmd & DO_LIST && server_response */
821
822   return RETRFINISHED;
823 }
824
825 /* A one-file FTP loop.  This is the part where FTP retrieval is
826    retried, and retried, and retried, and...
827
828    This loop either gets commands from con, or (if ON_YOUR_OWN is
829    set), makes them up to retrieve the file given by the URL.  */
830 static uerr_t
831 ftp_loop_internal (struct urlinfo *u, struct fileinfo *f, ccon *con)
832 {
833   static int first_retrieval = 1;
834
835   int count, orig_lp;
836   long restval, len;
837   char *tms, *tmrate, *locf;
838   uerr_t err;
839   struct stat st;
840
841   if (!u->local)
842     u->local = url_filename (u);
843
844   if (opt.noclobber && file_exists_p (u->local))
845     {
846       logprintf (LOG_VERBOSE,
847                  _("File `%s' already there, not retrieving.\n"), u->local);
848       /* If the file is there, we suppose it's retrieved OK.  */
849       return RETROK;
850     }
851
852   /* Remove it if it's a link.  */
853   remove_link (u->local);
854   if (!opt.output_document)
855     locf = u->local;
856   else
857     locf = opt.output_document;
858
859   count = 0;
860
861   if (con->st & ON_YOUR_OWN)
862     con->st = ON_YOUR_OWN;
863
864   orig_lp = con->cmd & LEAVE_PENDING ? 1 : 0;
865
866   /* THE loop.  */
867   do
868     {
869       /* Increment the pass counter.  */
870       ++count;
871       /* Wait before the retrieval (unless this is the very first
872          retrieval).
873          Check if we are retrying or not, wait accordingly - HEH */
874       if (!first_retrieval && (opt.wait || (count && opt.waitretry)))
875         {
876           if (count)
877             {
878               if (count<opt.waitretry)
879                 sleep(count);
880               else
881                 sleep(opt.waitretry);
882             }
883           else
884             sleep (opt.wait);
885         }
886       if (first_retrieval)
887         first_retrieval = 0;
888       if (con->st & ON_YOUR_OWN)
889         {
890           con->cmd = 0;
891           con->cmd |= (DO_RETR | LEAVE_PENDING);
892           if (rbuf_initialized_p (&con->rbuf))
893             con->cmd &= ~ (DO_LOGIN | DO_CWD);
894           else
895             con->cmd |= (DO_LOGIN | DO_CWD);
896         }
897       else /* not on your own */
898         {
899           if (rbuf_initialized_p (&con->rbuf))
900             con->cmd &= ~DO_LOGIN;
901           else
902             con->cmd |= DO_LOGIN;
903           if (con->st & DONE_CWD)
904             con->cmd &= ~DO_CWD;
905           else
906             con->cmd |= DO_CWD;
907         }
908       /* Assume no restarting.  */
909       restval = 0L;
910       if ((count > 1 || opt.always_rest)
911           && !(con->cmd & DO_LIST)
912           && file_exists_p (u->local))
913         if (stat (u->local, &st) == 0)
914           restval = st.st_size;
915       /* Get the current time string.  */
916       tms = time_str (NULL);
917       /* Print fetch message, if opt.verbose.  */
918       if (opt.verbose)
919         {
920           char *hurl = str_url (u->proxy ? u->proxy : u, 1);
921           char tmp[15];
922           strcpy (tmp, "        ");
923           if (count > 1)
924             sprintf (tmp, _("(try:%2d)"), count);
925           logprintf (LOG_VERBOSE, "--%s--  %s\n  %s => `%s'\n",
926                      tms, hurl, tmp, locf);
927 #ifdef WINDOWS
928           ws_changetitle (hurl, 1);
929 #endif
930           free (hurl);
931         }
932       /* Send getftp the proper length, if fileinfo was provided.  */
933       if (f)
934         len = f->size;
935       else
936         len = 0;
937       err = getftp (u, &len, restval, con);
938       /* Time?  */
939       tms = time_str (NULL);
940       tmrate = rate (len - restval, con->dltime);
941
942       if (!rbuf_initialized_p (&con->rbuf))
943         con->st &= ~DONE_CWD;
944       else
945         con->st |= DONE_CWD;
946
947       switch (err)
948         {
949         case HOSTERR: case CONREFUSED: case FWRITEERR: case FOPENERR:
950         case FTPNSFOD: case FTPLOGINC: case FTPNOPASV:
951           /* Fatal errors, give up.  */
952           return err;
953           break;
954         case CONSOCKERR: case CONERROR: case FTPSRVERR: case FTPRERR:
955         case WRITEFAILED: case FTPUNKNOWNTYPE: case CONPORTERR:
956         case BINDERR: case LISTENERR: case ACCEPTERR:
957         case FTPPORTERR: case FTPLOGREFUSED: case FTPINVPASV:
958           printwhat (count, opt.ntry);
959           /* non-fatal errors */
960           continue;
961           break;
962         case FTPRETRINT:
963           /* If the control connection was closed, the retrieval
964              will be considered OK if f->size == len.  */
965           if (!f || len != f->size)
966             {
967               printwhat (count, opt.ntry);
968               continue;
969             }
970           break;
971         case RETRFINISHED:
972           /* Great!  */
973           break;
974         default:
975           /* Not as great.  */
976           abort ();
977         }
978
979       /* If we get out of the switch above without continue'ing, we've
980          successfully downloaded a file.  Remember this fact. */
981       downloaded_file(FILE_DOWNLOADED_NORMALLY, locf);
982
983       if (con->st & ON_YOUR_OWN)
984         {
985           CLOSE (RBUF_FD (&con->rbuf));
986           rbuf_uninitialize (&con->rbuf);
987         }
988       logprintf (LOG_VERBOSE, _("%s (%s) - `%s' saved [%ld]\n\n"),
989                  tms, tmrate, locf, len);
990       logprintf (LOG_NONVERBOSE, "%s URL: %s [%ld] -> \"%s\" [%d]\n",
991                  tms, u->url, len, locf, count);
992
993       if ((con->cmd & DO_LIST))
994         /* This is a directory listing file. */
995         {
996           if (!opt.remove_listing)
997             /* --dont-remove-listing was specified, so do count this towards the
998                number of bytes and files downloaded. */
999             {
1000               opt.downloaded += len;
1001               opt.numurls++;
1002             }
1003
1004           /* Deletion of listing files is not controlled by --delete-after, but
1005              by the more specific option --dont-remove-listing, and the code
1006              to do this deletion is in another function. */
1007         }
1008       else
1009         /* This is not a directory listing file. */
1010         {
1011           /* Unlike directory listing files, don't pretend normal files weren't
1012              downloaded if they're going to be deleted.  People seeding proxies,
1013              for instance, may want to know how many bytes and files they've
1014              downloaded through it. */
1015           opt.downloaded += len;
1016           opt.numurls++;
1017
1018           if (opt.delete_after)
1019             {
1020               DEBUGP (("Removing file due to --delete-after in"
1021                        " ftp_loop_internal():\n"));
1022               logprintf (LOG_VERBOSE, _("Removing %s.\n"), locf);
1023               if (unlink (locf))
1024                 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1025             }
1026         }
1027       
1028       /* Restore the original leave-pendingness.  */
1029       if (orig_lp)
1030         con->cmd |= LEAVE_PENDING;
1031       else
1032         con->cmd &= ~LEAVE_PENDING;
1033       return RETROK;
1034     } while (!opt.ntry || (count < opt.ntry));
1035
1036   if (rbuf_initialized_p (&con->rbuf) && (con->st & ON_YOUR_OWN))
1037     {
1038       CLOSE (RBUF_FD (&con->rbuf));
1039       rbuf_uninitialize (&con->rbuf);
1040     }
1041   return TRYLIMEXC;
1042 }
1043
1044 /* Return the directory listing in a reusable format.  The directory
1045    is specifed in u->dir.  */
1046 static struct fileinfo *
1047 ftp_get_listing (struct urlinfo *u, ccon *con)
1048 {
1049   struct fileinfo *f;
1050   uerr_t err;
1051   char *olocal = u->local;
1052   char *list_filename, *ofile;
1053
1054   con->st &= ~ON_YOUR_OWN;
1055   con->cmd |= (DO_LIST | LEAVE_PENDING);
1056   con->cmd &= ~DO_RETR;
1057   /* Get the listing filename.  */
1058   ofile = u->file;
1059   u->file = LIST_FILENAME;
1060   list_filename = url_filename (u);
1061   u->file = ofile;
1062   u->local = list_filename;
1063   DEBUGP ((_("Using `%s' as listing tmp file.\n"), list_filename));
1064   err = ftp_loop_internal (u, NULL, con);
1065   u->local = olocal;
1066   if (err == RETROK)
1067     f = ftp_parse_ls (list_filename);
1068   else
1069     f = NULL;
1070   if (opt.remove_listing)
1071     {
1072       if (unlink (list_filename))
1073         logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1074       else
1075         logprintf (LOG_VERBOSE, _("Removed `%s'.\n"), list_filename);
1076     }
1077   free (list_filename);
1078   con->cmd &= ~DO_LIST;
1079   return f;
1080 }
1081
1082 static uerr_t ftp_retrieve_dirs PARAMS ((struct urlinfo *, struct fileinfo *,
1083                                          ccon *));
1084 static uerr_t ftp_retrieve_glob PARAMS ((struct urlinfo *, ccon *, int));
1085 static struct fileinfo *delelement PARAMS ((struct fileinfo *,
1086                                             struct fileinfo **));
1087 static void freefileinfo PARAMS ((struct fileinfo *f));
1088
1089 /* Retrieve a list of files given in struct fileinfo linked list.  If
1090    a file is a symbolic link, do not retrieve it, but rather try to
1091    set up a similar link on the local disk, if the symlinks are
1092    supported.
1093
1094    If opt.recursive is set, after all files have been retrieved,
1095    ftp_retrieve_dirs will be called to retrieve the directories.  */
1096 static uerr_t
1097 ftp_retrieve_list (struct urlinfo *u, struct fileinfo *f, ccon *con)
1098 {
1099   static int depth = 0;
1100   uerr_t err;
1101   char *olocal, *ofile;
1102   struct fileinfo *orig;
1103   long local_size;
1104   time_t tml;
1105   int dlthis;
1106
1107   /* Increase the depth.  */
1108   ++depth;
1109   if (opt.reclevel != INFINITE_RECURSION && depth > opt.reclevel)
1110     {
1111       DEBUGP ((_("Recursion depth %d exceeded max. depth %d.\n"),
1112                depth, opt.reclevel));
1113       --depth;
1114       return RECLEVELEXC;
1115     }
1116
1117   assert (f != NULL);
1118   orig = f;
1119
1120   con->st &= ~ON_YOUR_OWN;
1121   if (!(con->st & DONE_CWD))
1122     con->cmd |= DO_CWD;
1123   else
1124     con->cmd &= ~DO_CWD;
1125   con->cmd |= (DO_RETR | LEAVE_PENDING);
1126
1127   if (!rbuf_initialized_p (&con->rbuf))
1128     con->cmd |= DO_LOGIN;
1129   else
1130     con->cmd &= ~DO_LOGIN;
1131
1132   err = RETROK;                 /* in case it's not used */
1133
1134   while (f)
1135     {
1136       if (opt.quota && opt.downloaded > opt.quota)
1137         {
1138           --depth;
1139           return QUOTEXC;
1140         }
1141       olocal = u->local;
1142       ofile = u->file;
1143       u->file = f->name;
1144       u->local = url_filename (u);
1145       err = RETROK;
1146
1147       dlthis = 1;
1148       if (opt.timestamping && f->type == FT_PLAINFILE)
1149         {
1150           struct stat st;
1151           /* If conversion of HTML files retrieved via FTP is ever implemented,
1152              we'll need to stat() <file>.orig here when -K has been specified.
1153              I'm not implementing it now since files on an FTP server are much
1154              more likely than files on an HTTP server to legitimately have a
1155              .orig suffix. */
1156           if (!stat (u->local, &st))
1157             {
1158               /* Else, get it from the file.  */
1159               local_size = st.st_size;
1160               tml = st.st_mtime;
1161               if (local_size == f->size && tml >= f->tstamp)
1162                 {
1163                   logprintf (LOG_VERBOSE, _("\
1164 Server file no newer than local file `%s' -- not retrieving.\n\n"), u->local);
1165                   dlthis = 0;
1166                 }
1167               else if (local_size != f->size)
1168                 {
1169                   logprintf (LOG_VERBOSE, _("\
1170 The sizes do not match (local %ld) -- retrieving.\n"), local_size);
1171                 }
1172             }
1173         }       /* opt.timestamping && f->type == FT_PLAINFILE */
1174       switch (f->type)
1175         {
1176         case FT_SYMLINK:
1177           /* If opt.retr_symlinks is defined, we treat symlinks as
1178              if they were normal files.  There is currently no way
1179              to distinguish whether they might be directories, and
1180              follow them.  */
1181           if (!opt.retr_symlinks)
1182             {
1183 #ifdef HAVE_SYMLINK
1184               if (!f->linkto)
1185                 logputs (LOG_NOTQUIET,
1186                          _("Invalid name of the symlink, skipping.\n"));
1187               else
1188                 {
1189                   struct stat st;
1190                   /* Check whether we already have the correct
1191                      symbolic link.  */
1192                   int rc = lstat (u->local, &st);
1193                   if (rc == 0)
1194                     {
1195                       size_t len = strlen (f->linkto) + 1;
1196                       if (S_ISLNK (st.st_mode))
1197                         {
1198                           char *link_target = (char *)alloca (len);
1199                           size_t n = readlink (u->local, link_target, len);
1200                           if ((n == len - 1)
1201                               && (memcmp (link_target, f->linkto, n) == 0))
1202                             {
1203                               logprintf (LOG_VERBOSE, _("\
1204 Already have correct symlink %s -> %s\n\n"),
1205                                          u->local, f->linkto);
1206                               dlthis = 0;
1207                               break;
1208                             }
1209                         }
1210                     }
1211                   logprintf (LOG_VERBOSE, _("Creating symlink %s -> %s\n"),
1212                              u->local, f->linkto);
1213                   /* Unlink before creating symlink!  */
1214                   unlink (u->local);
1215                   if (symlink (f->linkto, u->local) == -1)
1216                     logprintf (LOG_NOTQUIET, "symlink: %s\n",
1217                                strerror (errno));
1218                   logputs (LOG_VERBOSE, "\n");
1219                 } /* have f->linkto */
1220 #else  /* not HAVE_SYMLINK */
1221               logprintf (LOG_NOTQUIET,
1222                          _("Symlinks not supported, skipping symlink `%s'.\n"),
1223                          u->local);
1224 #endif /* not HAVE_SYMLINK */
1225             }
1226           else                /* opt.retr_symlinks */
1227             {
1228               if (dlthis)
1229                 err = ftp_loop_internal (u, f, con);
1230             } /* opt.retr_symlinks */
1231           break;
1232         case FT_DIRECTORY:
1233           if (!opt.recursive)
1234             logprintf (LOG_NOTQUIET, _("Skipping directory `%s'.\n"),
1235                        f->name);
1236           break;
1237         case FT_PLAINFILE:
1238           /* Call the retrieve loop.  */
1239           if (dlthis)
1240             err = ftp_loop_internal (u, f, con);
1241           break;
1242         case FT_UNKNOWN:
1243           logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
1244                      f->name);
1245           break;
1246         }       /* switch */
1247
1248       /* Set the time-stamp information to the local file.  Symlinks
1249          are not to be stamped because it sets the stamp on the
1250          original.  :( */
1251       if (!opt.dfp
1252           && !(f->type == FT_SYMLINK && !opt.retr_symlinks)
1253           && f->tstamp != -1
1254           && dlthis
1255           && file_exists_p (u->local))
1256         {
1257           touch (u->local, f->tstamp);
1258         }
1259       else if (f->tstamp == -1)
1260         logprintf (LOG_NOTQUIET, _("%s: corrupt time-stamp.\n"), u->local);
1261
1262       if (f->perms && f->type == FT_PLAINFILE && dlthis)
1263         chmod (u->local, f->perms);
1264       else
1265         DEBUGP (("Unrecognized permissions for %s.\n", u->local));
1266
1267       free (u->local);
1268       u->local = olocal;
1269       u->file = ofile;
1270       /* Break on fatals.  */
1271       if (err == QUOTEXC || err == HOSTERR || err == FWRITEERR)
1272         break;
1273       con->cmd &= ~ (DO_CWD | DO_LOGIN);
1274       f = f->next;
1275     } /* while */
1276   /* We do not want to call ftp_retrieve_dirs here */
1277   if (opt.recursive &&
1278       !(opt.reclevel != INFINITE_RECURSION && depth >= opt.reclevel))
1279     err = ftp_retrieve_dirs (u, orig, con);
1280   else if (opt.recursive)
1281     DEBUGP ((_("Will not retrieve dirs since depth is %d (max %d).\n"),
1282              depth, opt.reclevel));
1283   --depth;
1284   return err;
1285 }
1286
1287 /* Retrieve the directories given in a file list.  This function works
1288    by simply going through the linked list and calling
1289    ftp_retrieve_glob on each directory entry.  The function knows
1290    about excluded directories.  */
1291 static uerr_t
1292 ftp_retrieve_dirs (struct urlinfo *u, struct fileinfo *f, ccon *con)
1293 {
1294   char *odir;
1295   char *current_container = NULL;
1296   int current_length = 0;
1297
1298   for (; f; f = f->next)
1299     {
1300       int len;
1301
1302       if (opt.quota && opt.downloaded > opt.quota)
1303         break;
1304       if (f->type != FT_DIRECTORY)
1305         continue;
1306       odir = u->dir;
1307       len = 1 + strlen (u->dir) + 1 + strlen (f->name) + 1;
1308       /* Allocate u->dir off stack, but reallocate only if a larger
1309          string is needed.  */
1310       if (len > current_length)
1311         current_container = (char *)alloca (len);
1312       u->dir = current_container;
1313       /* When retrieving recursively, all directories must be
1314          absolute.  This restriction will (hopefully!) be lifted in
1315          the future.  */
1316       sprintf (u->dir, "/%s%s%s", odir + (*odir == '/'),
1317               (!*odir || (*odir == '/' && !* (odir + 1))) ? "" : "/", f->name);
1318       if (!accdir (u->dir, ALLABS))
1319         {
1320           logprintf (LOG_VERBOSE, _("\
1321 Not descending to `%s' as it is excluded/not-included.\n"), u->dir);
1322           u->dir = odir;
1323           continue;
1324         }
1325       con->st &= ~DONE_CWD;
1326       ftp_retrieve_glob (u, con, GETALL);
1327       /* Set the time-stamp?  */
1328       u->dir = odir;
1329     }
1330   if (opt.quota && opt.downloaded > opt.quota)
1331     return QUOTEXC;
1332   else
1333     return RETROK;
1334 }
1335
1336
1337 /* A near-top-level function to retrieve the files in a directory.
1338    The function calls ftp_get_listing, to get a linked list of files.
1339    Then it weeds out the file names that do not match the pattern.
1340    ftp_retrieve_list is called with this updated list as an argument.
1341
1342    If the argument ACTION is GETONE, just download the file (but first
1343    get the listing, so that the time-stamp is heeded); if it's GLOBALL,
1344    use globbing; if it's GETALL, download the whole directory.  */
1345 static uerr_t
1346 ftp_retrieve_glob (struct urlinfo *u, ccon *con, int action)
1347 {
1348   struct fileinfo *orig, *start;
1349   uerr_t res;
1350
1351   con->cmd |= LEAVE_PENDING;
1352
1353   orig = ftp_get_listing (u, con);
1354   start = orig;
1355   /* First: weed out that do not conform the global rules given in
1356      opt.accepts and opt.rejects.  */
1357   if (opt.accepts || opt.rejects)
1358     {
1359       struct fileinfo *f = orig;
1360
1361       while (f)
1362         {
1363           if (f->type != FT_DIRECTORY && !acceptable (f->name))
1364             {
1365               logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"), f->name);
1366               f = delelement (f, &start);
1367             }
1368           else
1369             f = f->next;
1370         }
1371     }
1372   /* Now weed out the files that do not match our globbing pattern.
1373      If we are dealing with a globbing pattern, that is.  */
1374   if (*u->file && (action == GLOBALL || action == GETONE))
1375     {
1376       int matchres = 0;
1377       struct fileinfo *f = start;
1378
1379       while (f)
1380         {
1381           matchres = fnmatch (u->file, f->name, 0);
1382           if (matchres == -1)
1383             {
1384               logprintf (LOG_NOTQUIET, "%s: %s\n", u->local,
1385                          strerror (errno));
1386               break;
1387             }
1388           if (matchres == FNM_NOMATCH)
1389             f = delelement (f, &start); /* delete the element from the list */
1390           else
1391             f = f->next;        /* leave the element in the list */
1392         }
1393       if (matchres == -1)
1394         {
1395           freefileinfo (start);
1396           return RETRBADPATTERN;
1397         }
1398     }
1399   res = RETROK;
1400   if (start)
1401     {
1402       /* Just get everything.  */
1403       ftp_retrieve_list (u, start, con);
1404     }
1405   else if (!start)
1406     {
1407       if (action == GLOBALL)
1408         {
1409           /* No luck.  */
1410           /* #### This message SUCKS.  We should see what was the
1411              reason that nothing was retrieved.  */
1412           logprintf (LOG_VERBOSE, _("No matches on pattern `%s'.\n"), u->file);
1413         }
1414       else /* GETONE or GETALL */
1415         {
1416           /* Let's try retrieving it anyway.  */
1417           con->st |= ON_YOUR_OWN;
1418           res = ftp_loop_internal (u, NULL, con);
1419           return res;
1420         }
1421     }
1422   freefileinfo (start);
1423   if (opt.quota && opt.downloaded > opt.quota)
1424     return QUOTEXC;
1425   else
1426     /* #### Should we return `res' here?  */
1427     return RETROK;
1428 }
1429
1430 /* The wrapper that calls an appropriate routine according to contents
1431    of URL.  Inherently, its capabilities are limited on what can be
1432    encoded into a URL.  */
1433 uerr_t
1434 ftp_loop (struct urlinfo *u, int *dt)
1435 {
1436   ccon con;                     /* FTP connection */
1437   uerr_t res;
1438
1439   *dt = 0;
1440
1441   rbuf_uninitialize (&con.rbuf);
1442   con.st = ON_YOUR_OWN;
1443   res = RETROK;                 /* in case it's not used */
1444
1445   /* If the file name is empty, the user probably wants a directory
1446      index.  We'll provide one, properly HTML-ized.  Unless
1447      opt.htmlify is 0, of course.  :-) */
1448   if (!*u->file && !opt.recursive)
1449     {
1450       struct fileinfo *f = ftp_get_listing (u, &con);
1451
1452       if (f)
1453         {
1454           if (opt.htmlify)
1455             {
1456               char *filename = (opt.output_document
1457                                 ? xstrdup (opt.output_document)
1458                                 : (u->local ? xstrdup (u->local)
1459                                    : url_filename (u)));
1460               res = ftp_index (filename, u, f);
1461               if (res == FTPOK && opt.verbose)
1462                 {
1463                   if (!opt.output_document)
1464                     {
1465                       struct stat st;
1466                       long sz;
1467                       if (stat (filename, &st) == 0)
1468                         sz = st.st_size;
1469                       else
1470                         sz = -1;
1471                       logprintf (LOG_NOTQUIET,
1472                                  _("Wrote HTML-ized index to `%s' [%ld].\n"),
1473                                  filename, sz);
1474                     }
1475                   else
1476                     logprintf (LOG_NOTQUIET,
1477                                _("Wrote HTML-ized index to `%s'.\n"),
1478                                filename);
1479                 }
1480               free (filename);
1481             }
1482           freefileinfo (f);
1483         }
1484     }
1485   else
1486     {
1487       int wild = has_wildcards_p (u->file);
1488       if ((opt.ftp_glob && wild) || opt.recursive || opt.timestamping)
1489         {
1490           /* ftp_retrieve_glob is a catch-all function that gets called
1491              if we need globbing, time-stamping or recursion.  Its
1492              third argument is just what we really need.  */
1493           ftp_retrieve_glob (u, &con,
1494                              (opt.ftp_glob && wild) ? GLOBALL : GETONE);
1495         }
1496       else
1497         res = ftp_loop_internal (u, NULL, &con);
1498     }
1499   if (res == FTPOK)
1500     res = RETROK;
1501   if (res == RETROK)
1502     *dt |= RETROKF;
1503   /* If a connection was left, quench it.  */
1504   if (rbuf_initialized_p (&con.rbuf))
1505     CLOSE (RBUF_FD (&con.rbuf));
1506   return res;
1507 }
1508
1509 /* Delete an element from the fileinfo linked list.  Returns the
1510    address of the next element, or NULL if the list is exhausted.  It
1511    can modify the start of the list.  */
1512 static struct fileinfo *
1513 delelement (struct fileinfo *f, struct fileinfo **start)
1514 {
1515   struct fileinfo *prev = f->prev;
1516   struct fileinfo *next = f->next;
1517
1518   free (f->name);
1519   FREE_MAYBE (f->linkto);
1520   free (f);
1521
1522   if (next)
1523     next->prev = prev;
1524   if (prev)
1525     prev->next = next;
1526   else
1527     *start = next;
1528   return next;
1529 }
1530
1531 /* Free the fileinfo linked list of files.  */
1532 static void
1533 freefileinfo (struct fileinfo *f)
1534 {
1535   while (f)
1536     {
1537       struct fileinfo *next = f->next;
1538       free (f->name);
1539       if (f->linkto)
1540         free (f->linkto);
1541       free (f);
1542       f = next;
1543     }
1544 }