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