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