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