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