]> sjero.net Git - wget/blob - src/ftp.c
[svn] Fix -O timestamp bug.
[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           /* #### This code repeats in http.c and ftp.c.  Move it to a
1374              function!  */
1375           const char *fl = NULL;
1376           if (opt.output_document)
1377             {
1378               if (opt.od_known_regular)
1379                 fl = opt.output_document;
1380             }
1381           else
1382             fl = u->local;
1383           if (fl)
1384             touch (fl, f->tstamp);
1385         }
1386       else if (f->tstamp == -1)
1387         logprintf (LOG_NOTQUIET, _("%s: corrupt time-stamp.\n"), u->local);
1388
1389       if (f->perms && f->type == FT_PLAINFILE && dlthis)
1390         chmod (u->local, f->perms);
1391       else
1392         DEBUGP (("Unrecognized permissions for %s.\n", u->local));
1393
1394       xfree (u->local);
1395       u->local = olocal;
1396       u->file = ofile;
1397       /* Break on fatals.  */
1398       if (err == QUOTEXC || err == HOSTERR || err == FWRITEERR)
1399         break;
1400       con->cmd &= ~ (DO_CWD | DO_LOGIN);
1401       f = f->next;
1402     } /* while */
1403   /* We do not want to call ftp_retrieve_dirs here */
1404   if (opt.recursive &&
1405       !(opt.reclevel != INFINITE_RECURSION && depth >= opt.reclevel))
1406     err = ftp_retrieve_dirs (u, orig, con);
1407   else if (opt.recursive)
1408     DEBUGP ((_("Will not retrieve dirs since depth is %d (max %d).\n"),
1409              depth, opt.reclevel));
1410   --depth;
1411   return err;
1412 }
1413
1414 /* Retrieve the directories given in a file list.  This function works
1415    by simply going through the linked list and calling
1416    ftp_retrieve_glob on each directory entry.  The function knows
1417    about excluded directories.  */
1418 static uerr_t
1419 ftp_retrieve_dirs (struct urlinfo *u, struct fileinfo *f, ccon *con)
1420 {
1421   char *odir;
1422   char *current_container = NULL;
1423   int current_length = 0;
1424
1425   for (; f; f = f->next)
1426     {
1427       int len;
1428
1429       if (downloaded_exceeds_quota ())
1430         break;
1431       if (f->type != FT_DIRECTORY)
1432         continue;
1433       odir = u->dir;
1434       len = 1 + strlen (u->dir) + 1 + strlen (f->name) + 1;
1435       /* Allocate u->dir off stack, but reallocate only if a larger
1436          string is needed.  */
1437       if (len > current_length)
1438         current_container = (char *)alloca (len);
1439       u->dir = current_container;
1440       /* When retrieving recursively, all directories must be
1441          absolute.  This restriction will (hopefully!) be lifted in
1442          the future.  */
1443       sprintf (u->dir, "/%s%s%s", odir + (*odir == '/'),
1444               (!*odir || (*odir == '/' && !* (odir + 1))) ? "" : "/", f->name);
1445       if (!accdir (u->dir, ALLABS))
1446         {
1447           logprintf (LOG_VERBOSE, _("\
1448 Not descending to `%s' as it is excluded/not-included.\n"), u->dir);
1449           u->dir = odir;
1450           continue;
1451         }
1452       con->st &= ~DONE_CWD;
1453       ftp_retrieve_glob (u, con, GETALL);
1454       /* Set the time-stamp?  */
1455       u->dir = odir;
1456     }
1457   if (opt.quota && opt.downloaded > opt.quota)
1458     return QUOTEXC;
1459   else
1460     return RETROK;
1461 }
1462
1463
1464 /* A near-top-level function to retrieve the files in a directory.
1465    The function calls ftp_get_listing, to get a linked list of files.
1466    Then it weeds out the file names that do not match the pattern.
1467    ftp_retrieve_list is called with this updated list as an argument.
1468
1469    If the argument ACTION is GETONE, just download the file (but first
1470    get the listing, so that the time-stamp is heeded); if it's GLOBALL,
1471    use globbing; if it's GETALL, download the whole directory.  */
1472 static uerr_t
1473 ftp_retrieve_glob (struct urlinfo *u, ccon *con, int action)
1474 {
1475   struct fileinfo *orig, *start;
1476   uerr_t res;
1477
1478   con->cmd |= LEAVE_PENDING;
1479
1480   orig = ftp_get_listing (u, con);
1481   start = orig;
1482   /* First: weed out that do not conform the global rules given in
1483      opt.accepts and opt.rejects.  */
1484   if (opt.accepts || opt.rejects)
1485     {
1486       struct fileinfo *f = orig;
1487
1488       while (f)
1489         {
1490           if (f->type != FT_DIRECTORY && !acceptable (f->name))
1491             {
1492               logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"), f->name);
1493               f = delelement (f, &start);
1494             }
1495           else
1496             f = f->next;
1497         }
1498     }
1499   /* Now weed out the files that do not match our globbing pattern.
1500      If we are dealing with a globbing pattern, that is.  */
1501   if (*u->file && (action == GLOBALL || action == GETONE))
1502     {
1503       int matchres = 0;
1504       struct fileinfo *f = start;
1505
1506       while (f)
1507         {
1508           matchres = fnmatch (u->file, f->name, 0);
1509           if (matchres == -1)
1510             {
1511               logprintf (LOG_NOTQUIET, "%s: %s\n", u->local,
1512                          strerror (errno));
1513               break;
1514             }
1515           if (matchres == FNM_NOMATCH)
1516             f = delelement (f, &start); /* delete the element from the list */
1517           else
1518             f = f->next;        /* leave the element in the list */
1519         }
1520       if (matchres == -1)
1521         {
1522           freefileinfo (start);
1523           return RETRBADPATTERN;
1524         }
1525     }
1526   res = RETROK;
1527   if (start)
1528     {
1529       /* Just get everything.  */
1530       ftp_retrieve_list (u, start, con);
1531     }
1532   else if (!start)
1533     {
1534       if (action == GLOBALL)
1535         {
1536           /* No luck.  */
1537           /* #### This message SUCKS.  We should see what was the
1538              reason that nothing was retrieved.  */
1539           logprintf (LOG_VERBOSE, _("No matches on pattern `%s'.\n"), u->file);
1540         }
1541       else /* GETONE or GETALL */
1542         {
1543           /* Let's try retrieving it anyway.  */
1544           con->st |= ON_YOUR_OWN;
1545           res = ftp_loop_internal (u, NULL, con);
1546           return res;
1547         }
1548     }
1549   freefileinfo (start);
1550   if (downloaded_exceeds_quota ())
1551     return QUOTEXC;
1552   else
1553     /* #### Should we return `res' here?  */
1554     return RETROK;
1555 }
1556
1557 /* The wrapper that calls an appropriate routine according to contents
1558    of URL.  Inherently, its capabilities are limited on what can be
1559    encoded into a URL.  */
1560 uerr_t
1561 ftp_loop (struct urlinfo *u, int *dt)
1562 {
1563   ccon con;                     /* FTP connection */
1564   uerr_t res;
1565
1566   *dt = 0;
1567
1568   rbuf_uninitialize (&con.rbuf);
1569   con.st = ON_YOUR_OWN;
1570   res = RETROK;                 /* in case it's not used */
1571
1572   /* If the file name is empty, the user probably wants a directory
1573      index.  We'll provide one, properly HTML-ized.  Unless
1574      opt.htmlify is 0, of course.  :-) */
1575   if (!*u->file && !opt.recursive)
1576     {
1577       struct fileinfo *f = ftp_get_listing (u, &con);
1578
1579       if (f)
1580         {
1581           if (opt.htmlify)
1582             {
1583               char *filename = (opt.output_document
1584                                 ? xstrdup (opt.output_document)
1585                                 : (u->local ? xstrdup (u->local)
1586                                    : url_filename (u)));
1587               res = ftp_index (filename, u, f);
1588               if (res == FTPOK && opt.verbose)
1589                 {
1590                   if (!opt.output_document)
1591                     {
1592                       struct stat st;
1593                       long sz;
1594                       if (stat (filename, &st) == 0)
1595                         sz = st.st_size;
1596                       else
1597                         sz = -1;
1598                       logprintf (LOG_NOTQUIET,
1599                                  _("Wrote HTML-ized index to `%s' [%ld].\n"),
1600                                  filename, sz);
1601                     }
1602                   else
1603                     logprintf (LOG_NOTQUIET,
1604                                _("Wrote HTML-ized index to `%s'.\n"),
1605                                filename);
1606                 }
1607               xfree (filename);
1608             }
1609           freefileinfo (f);
1610         }
1611     }
1612   else
1613     {
1614       int wild = has_wildcards_p (u->file);
1615       if ((opt.ftp_glob && wild) || opt.recursive || opt.timestamping)
1616         {
1617           /* ftp_retrieve_glob is a catch-all function that gets called
1618              if we need globbing, time-stamping or recursion.  Its
1619              third argument is just what we really need.  */
1620           ftp_retrieve_glob (u, &con,
1621                              (opt.ftp_glob && wild) ? GLOBALL : GETONE);
1622         }
1623       else
1624         res = ftp_loop_internal (u, NULL, &con);
1625     }
1626   if (res == FTPOK)
1627     res = RETROK;
1628   if (res == RETROK)
1629     *dt |= RETROKF;
1630   /* If a connection was left, quench it.  */
1631   if (rbuf_initialized_p (&con.rbuf))
1632     CLOSE (RBUF_FD (&con.rbuf));
1633   FREE_MAYBE (pwd);
1634   pwd = NULL;
1635   return res;
1636 }
1637
1638 /* Delete an element from the fileinfo linked list.  Returns the
1639    address of the next element, or NULL if the list is exhausted.  It
1640    can modify the start of the list.  */
1641 static struct fileinfo *
1642 delelement (struct fileinfo *f, struct fileinfo **start)
1643 {
1644   struct fileinfo *prev = f->prev;
1645   struct fileinfo *next = f->next;
1646
1647   xfree (f->name);
1648   FREE_MAYBE (f->linkto);
1649   xfree (f);
1650
1651   if (next)
1652     next->prev = prev;
1653   if (prev)
1654     prev->next = next;
1655   else
1656     *start = next;
1657   return next;
1658 }
1659
1660 /* Free the fileinfo linked list of files.  */
1661 static void
1662 freefileinfo (struct fileinfo *f)
1663 {
1664   while (f)
1665     {
1666       struct fileinfo *next = f->next;
1667       xfree (f->name);
1668       if (f->linkto)
1669         xfree (f->linkto);
1670       xfree (f);
1671       f = next;
1672     }
1673 }