]> sjero.net Git - wget/blob - src/ftp.c
[svn] Commit my url.c fix (space as unsafe character) and Jan's
[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   static int first_retrieval = 1;
952
953   int count, orig_lp;
954   long restval, len;
955   char *tms, *tmrate, *locf;
956   uerr_t err;
957   struct stat st;
958
959   if (!u->local)
960     u->local = url_filename (u);
961
962   if (opt.noclobber && file_exists_p (u->local))
963     {
964       logprintf (LOG_VERBOSE,
965                  _("File `%s' already there, not retrieving.\n"), u->local);
966       /* If the file is there, we suppose it's retrieved OK.  */
967       return RETROK;
968     }
969
970   /* Remove it if it's a link.  */
971   remove_link (u->local);
972   if (!opt.output_document)
973     locf = u->local;
974   else
975     locf = opt.output_document;
976
977   count = 0;
978
979   if (con->st & ON_YOUR_OWN)
980     con->st = ON_YOUR_OWN;
981
982   orig_lp = con->cmd & LEAVE_PENDING ? 1 : 0;
983
984   /* THE loop.  */
985   do
986     {
987       /* Increment the pass counter.  */
988       ++count;
989       /* Wait before the retrieval (unless this is the very first
990          retrieval).
991          Check if we are retrying or not, wait accordingly - HEH */
992       if (!first_retrieval && (opt.wait || (count && opt.waitretry)))
993         {
994           if (count)
995             {
996               if (count<opt.waitretry)
997                 sleep(count);
998               else
999                 sleep(opt.waitretry);
1000             }
1001           else
1002             sleep (opt.wait);
1003         }
1004       if (first_retrieval)
1005         first_retrieval = 0;
1006       if (con->st & ON_YOUR_OWN)
1007         {
1008           con->cmd = 0;
1009           con->cmd |= (DO_RETR | LEAVE_PENDING);
1010           if (rbuf_initialized_p (&con->rbuf))
1011             con->cmd &= ~ (DO_LOGIN | DO_CWD);
1012           else
1013             con->cmd |= (DO_LOGIN | DO_CWD);
1014         }
1015       else /* not on your own */
1016         {
1017           if (rbuf_initialized_p (&con->rbuf))
1018             con->cmd &= ~DO_LOGIN;
1019           else
1020             con->cmd |= DO_LOGIN;
1021           if (con->st & DONE_CWD)
1022             con->cmd &= ~DO_CWD;
1023           else
1024             con->cmd |= DO_CWD;
1025         }
1026       /* Assume no restarting.  */
1027       restval = 0L;
1028       if ((count > 1 || opt.always_rest)
1029           && !(con->cmd & DO_LIST)
1030           && file_exists_p (u->local))
1031         if (stat (u->local, &st) == 0)
1032           restval = st.st_size;
1033       /* Get the current time string.  */
1034       tms = time_str (NULL);
1035       /* Print fetch message, if opt.verbose.  */
1036       if (opt.verbose)
1037         {
1038           char *hurl = str_url (u->proxy ? u->proxy : u, 1);
1039           char tmp[15];
1040           strcpy (tmp, "        ");
1041           if (count > 1)
1042             sprintf (tmp, _("(try:%2d)"), count);
1043           logprintf (LOG_VERBOSE, "--%s--  %s\n  %s => `%s'\n",
1044                      tms, hurl, tmp, locf);
1045 #ifdef WINDOWS
1046           ws_changetitle (hurl, 1);
1047 #endif
1048           xfree (hurl);
1049         }
1050       /* Send getftp the proper length, if fileinfo was provided.  */
1051       if (f)
1052         len = f->size;
1053       else
1054         len = 0;
1055       err = getftp (u, &len, restval, con);
1056       /* Time?  */
1057       tms = time_str (NULL);
1058       tmrate = rate (len - restval, con->dltime);
1059
1060       if (!rbuf_initialized_p (&con->rbuf))
1061         con->st &= ~DONE_CWD;
1062       else
1063         con->st |= DONE_CWD;
1064
1065       switch (err)
1066         {
1067         case HOSTERR: case CONREFUSED: case FWRITEERR: case FOPENERR:
1068         case FTPNSFOD: case FTPLOGINC: case FTPNOPASV:
1069           /* Fatal errors, give up.  */
1070           return err;
1071           break;
1072         case CONSOCKERR: case CONERROR: case FTPSRVERR: case FTPRERR:
1073         case WRITEFAILED: case FTPUNKNOWNTYPE: case CONPORTERR:
1074         case BINDERR: case LISTENERR: case ACCEPTERR:
1075         case FTPPORTERR: case FTPLOGREFUSED: case FTPINVPASV:
1076           printwhat (count, opt.ntry);
1077           /* non-fatal errors */
1078           continue;
1079           break;
1080         case FTPRETRINT:
1081           /* If the control connection was closed, the retrieval
1082              will be considered OK if f->size == len.  */
1083           if (!f || len != f->size)
1084             {
1085               printwhat (count, opt.ntry);
1086               continue;
1087             }
1088           break;
1089         case RETRFINISHED:
1090           /* Great!  */
1091           break;
1092         default:
1093           /* Not as great.  */
1094           abort ();
1095         }
1096
1097       /* If we get out of the switch above without continue'ing, we've
1098          successfully downloaded a file.  Remember this fact. */
1099       downloaded_file(FILE_DOWNLOADED_NORMALLY, locf);
1100
1101       if (con->st & ON_YOUR_OWN)
1102         {
1103           CLOSE (RBUF_FD (&con->rbuf));
1104           rbuf_uninitialize (&con->rbuf);
1105         }
1106       logprintf (LOG_VERBOSE, _("%s (%s) - `%s' saved [%ld]\n\n"),
1107                  tms, tmrate, locf, len);
1108       if (!opt.verbose && !opt.quiet)
1109         {
1110           /* Need to hide the password from the URL.  The `if' is here
1111              so that we don't do the needless allocation every
1112              time. */
1113           char *hurl = str_url (u->proxy ? u->proxy : u, 1);
1114           logprintf (LOG_NONVERBOSE, "%s URL: %s [%ld] -> \"%s\" [%d]\n",
1115                      tms, hurl, len, locf, count);
1116           xfree (hurl);
1117         }
1118
1119       if ((con->cmd & DO_LIST))
1120         /* This is a directory listing file. */
1121         {
1122           if (!opt.remove_listing)
1123             /* --dont-remove-listing was specified, so do count this towards the
1124                number of bytes and files downloaded. */
1125             {
1126               downloaded_increase (len);
1127               opt.numurls++;
1128             }
1129
1130           /* Deletion of listing files is not controlled by --delete-after, but
1131              by the more specific option --dont-remove-listing, and the code
1132              to do this deletion is in another function. */
1133         }
1134       else
1135         /* This is not a directory listing file. */
1136         {
1137           /* Unlike directory listing files, don't pretend normal files weren't
1138              downloaded if they're going to be deleted.  People seeding proxies,
1139              for instance, may want to know how many bytes and files they've
1140              downloaded through it. */
1141           downloaded_increase (len);
1142           opt.numurls++;
1143
1144           if (opt.delete_after)
1145             {
1146               DEBUGP (("Removing file due to --delete-after in"
1147                        " ftp_loop_internal():\n"));
1148               logprintf (LOG_VERBOSE, _("Removing %s.\n"), locf);
1149               if (unlink (locf))
1150                 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1151             }
1152         }
1153       
1154       /* Restore the original leave-pendingness.  */
1155       if (orig_lp)
1156         con->cmd |= LEAVE_PENDING;
1157       else
1158         con->cmd &= ~LEAVE_PENDING;
1159       return RETROK;
1160     } while (!opt.ntry || (count < opt.ntry));
1161
1162   if (rbuf_initialized_p (&con->rbuf) && (con->st & ON_YOUR_OWN))
1163     {
1164       CLOSE (RBUF_FD (&con->rbuf));
1165       rbuf_uninitialize (&con->rbuf);
1166     }
1167   return TRYLIMEXC;
1168 }
1169
1170 /* Return the directory listing in a reusable format.  The directory
1171    is specifed in u->dir.  */
1172 static struct fileinfo *
1173 ftp_get_listing (struct urlinfo *u, ccon *con)
1174 {
1175   struct fileinfo *f;
1176   uerr_t err;
1177   char *olocal = u->local;
1178   char *list_filename, *ofile;
1179
1180   con->st &= ~ON_YOUR_OWN;
1181   con->cmd |= (DO_LIST | LEAVE_PENDING);
1182   con->cmd &= ~DO_RETR;
1183   /* Get the listing filename.  */
1184   ofile = u->file;
1185   u->file = LIST_FILENAME;
1186   list_filename = url_filename (u);
1187   u->file = ofile;
1188   u->local = list_filename;
1189   DEBUGP ((_("Using `%s' as listing tmp file.\n"), list_filename));
1190   err = ftp_loop_internal (u, NULL, con);
1191   u->local = olocal;
1192   if (err == RETROK)
1193     f = ftp_parse_ls (list_filename, host_type);
1194   else
1195     f = NULL;
1196   if (opt.remove_listing)
1197     {
1198       if (unlink (list_filename))
1199         logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1200       else
1201         logprintf (LOG_VERBOSE, _("Removed `%s'.\n"), list_filename);
1202     }
1203   xfree (list_filename);
1204   con->cmd &= ~DO_LIST;
1205   return f;
1206 }
1207
1208 static uerr_t ftp_retrieve_dirs PARAMS ((struct urlinfo *, struct fileinfo *,
1209                                          ccon *));
1210 static uerr_t ftp_retrieve_glob PARAMS ((struct urlinfo *, ccon *, int));
1211 static struct fileinfo *delelement PARAMS ((struct fileinfo *,
1212                                             struct fileinfo **));
1213 static void freefileinfo PARAMS ((struct fileinfo *f));
1214
1215 /* Retrieve a list of files given in struct fileinfo linked list.  If
1216    a file is a symbolic link, do not retrieve it, but rather try to
1217    set up a similar link on the local disk, if the symlinks are
1218    supported.
1219
1220    If opt.recursive is set, after all files have been retrieved,
1221    ftp_retrieve_dirs will be called to retrieve the directories.  */
1222 static uerr_t
1223 ftp_retrieve_list (struct urlinfo *u, struct fileinfo *f, ccon *con)
1224 {
1225   static int depth = 0;
1226   uerr_t err;
1227   char *olocal, *ofile;
1228   struct fileinfo *orig;
1229   long local_size;
1230   time_t tml;
1231   int dlthis;
1232
1233   /* Increase the depth.  */
1234   ++depth;
1235   if (opt.reclevel != INFINITE_RECURSION && depth > opt.reclevel)
1236     {
1237       DEBUGP ((_("Recursion depth %d exceeded max. depth %d.\n"),
1238                depth, opt.reclevel));
1239       --depth;
1240       return RECLEVELEXC;
1241     }
1242
1243   assert (f != NULL);
1244   orig = f;
1245
1246   con->st &= ~ON_YOUR_OWN;
1247   if (!(con->st & DONE_CWD))
1248     con->cmd |= DO_CWD;
1249   else
1250     con->cmd &= ~DO_CWD;
1251   con->cmd |= (DO_RETR | LEAVE_PENDING);
1252
1253   if (!rbuf_initialized_p (&con->rbuf))
1254     con->cmd |= DO_LOGIN;
1255   else
1256     con->cmd &= ~DO_LOGIN;
1257
1258   err = RETROK;                 /* in case it's not used */
1259
1260   while (f)
1261     {
1262       if (downloaded_exceeds_quota ())
1263         {
1264           --depth;
1265           return QUOTEXC;
1266         }
1267       olocal = u->local;
1268       ofile = u->file;
1269       u->file = f->name;
1270       u->local = url_filename (u);
1271       err = RETROK;
1272
1273       dlthis = 1;
1274       if (opt.timestamping && f->type == FT_PLAINFILE)
1275         {
1276           struct stat st;
1277           /* If conversion of HTML files retrieved via FTP is ever implemented,
1278              we'll need to stat() <file>.orig here when -K has been specified.
1279              I'm not implementing it now since files on an FTP server are much
1280              more likely than files on an HTTP server to legitimately have a
1281              .orig suffix. */
1282           if (!stat (u->local, &st))
1283             {
1284               /* Else, get it from the file.  */
1285               local_size = st.st_size;
1286               tml = st.st_mtime;
1287               if (local_size == f->size && tml >= f->tstamp)
1288                 {
1289                   logprintf (LOG_VERBOSE, _("\
1290 Server file no newer than local file `%s' -- not retrieving.\n\n"), u->local);
1291                   dlthis = 0;
1292                 }
1293               else if (local_size != f->size)
1294                 {
1295                   if (host_type == ST_VMS)
1296                     {
1297                       logprintf (LOG_VERBOSE, _("\
1298 Cannot compare sizes, remote system is VMS.\n"));
1299                       dlthis = 0;
1300                     }
1301                   else
1302                     {
1303                       logprintf (LOG_VERBOSE, _("\
1304 The sizes do not match (local %ld) -- retrieving.\n"), local_size);
1305                     }
1306                 }
1307             }
1308         }       /* opt.timestamping && f->type == FT_PLAINFILE */
1309       switch (f->type)
1310         {
1311         case FT_SYMLINK:
1312           /* If opt.retr_symlinks is defined, we treat symlinks as
1313              if they were normal files.  There is currently no way
1314              to distinguish whether they might be directories, and
1315              follow them.  */
1316           if (!opt.retr_symlinks)
1317             {
1318 #ifdef HAVE_SYMLINK
1319               if (!f->linkto)
1320                 logputs (LOG_NOTQUIET,
1321                          _("Invalid name of the symlink, skipping.\n"));
1322               else
1323                 {
1324                   struct stat st;
1325                   /* Check whether we already have the correct
1326                      symbolic link.  */
1327                   int rc = lstat (u->local, &st);
1328                   if (rc == 0)
1329                     {
1330                       size_t len = strlen (f->linkto) + 1;
1331                       if (S_ISLNK (st.st_mode))
1332                         {
1333                           char *link_target = (char *)alloca (len);
1334                           size_t n = readlink (u->local, link_target, len);
1335                           if ((n == len - 1)
1336                               && (memcmp (link_target, f->linkto, n) == 0))
1337                             {
1338                               logprintf (LOG_VERBOSE, _("\
1339 Already have correct symlink %s -> %s\n\n"),
1340                                          u->local, f->linkto);
1341                               dlthis = 0;
1342                               break;
1343                             }
1344                         }
1345                     }
1346                   logprintf (LOG_VERBOSE, _("Creating symlink %s -> %s\n"),
1347                              u->local, f->linkto);
1348                   /* Unlink before creating symlink!  */
1349                   unlink (u->local);
1350                   if (symlink (f->linkto, u->local) == -1)
1351                     logprintf (LOG_NOTQUIET, "symlink: %s\n",
1352                                strerror (errno));
1353                   logputs (LOG_VERBOSE, "\n");
1354                 } /* have f->linkto */
1355 #else  /* not HAVE_SYMLINK */
1356               logprintf (LOG_NOTQUIET,
1357                          _("Symlinks not supported, skipping symlink `%s'.\n"),
1358                          u->local);
1359 #endif /* not HAVE_SYMLINK */
1360             }
1361           else                /* opt.retr_symlinks */
1362             {
1363               if (dlthis)
1364                 err = ftp_loop_internal (u, f, con);
1365             } /* opt.retr_symlinks */
1366           break;
1367         case FT_DIRECTORY:
1368           if (!opt.recursive)
1369             logprintf (LOG_NOTQUIET, _("Skipping directory `%s'.\n"),
1370                        f->name);
1371           break;
1372         case FT_PLAINFILE:
1373           /* Call the retrieve loop.  */
1374           if (dlthis)
1375             err = ftp_loop_internal (u, f, con);
1376           break;
1377         case FT_UNKNOWN:
1378           logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
1379                      f->name);
1380           break;
1381         }       /* switch */
1382
1383       /* Set the time-stamp information to the local file.  Symlinks
1384          are not to be stamped because it sets the stamp on the
1385          original.  :( */
1386       if (!opt.dfp
1387           && !(f->type == FT_SYMLINK && !opt.retr_symlinks)
1388           && f->tstamp != -1
1389           && dlthis
1390           && file_exists_p (u->local))
1391         {
1392           touch (u->local, f->tstamp);
1393         }
1394       else if (f->tstamp == -1)
1395         logprintf (LOG_NOTQUIET, _("%s: corrupt time-stamp.\n"), u->local);
1396
1397       if (f->perms && f->type == FT_PLAINFILE && dlthis)
1398         chmod (u->local, f->perms);
1399       else
1400         DEBUGP (("Unrecognized permissions for %s.\n", u->local));
1401
1402       xfree (u->local);
1403       u->local = olocal;
1404       u->file = ofile;
1405       /* Break on fatals.  */
1406       if (err == QUOTEXC || err == HOSTERR || err == FWRITEERR)
1407         break;
1408       con->cmd &= ~ (DO_CWD | DO_LOGIN);
1409       f = f->next;
1410     } /* while */
1411   /* We do not want to call ftp_retrieve_dirs here */
1412   if (opt.recursive &&
1413       !(opt.reclevel != INFINITE_RECURSION && depth >= opt.reclevel))
1414     err = ftp_retrieve_dirs (u, orig, con);
1415   else if (opt.recursive)
1416     DEBUGP ((_("Will not retrieve dirs since depth is %d (max %d).\n"),
1417              depth, opt.reclevel));
1418   --depth;
1419   return err;
1420 }
1421
1422 /* Retrieve the directories given in a file list.  This function works
1423    by simply going through the linked list and calling
1424    ftp_retrieve_glob on each directory entry.  The function knows
1425    about excluded directories.  */
1426 static uerr_t
1427 ftp_retrieve_dirs (struct urlinfo *u, struct fileinfo *f, ccon *con)
1428 {
1429   char *odir;
1430   char *current_container = NULL;
1431   int current_length = 0;
1432
1433   for (; f; f = f->next)
1434     {
1435       int len;
1436
1437       if (downloaded_exceeds_quota ())
1438         break;
1439       if (f->type != FT_DIRECTORY)
1440         continue;
1441       odir = u->dir;
1442       len = 1 + strlen (u->dir) + 1 + strlen (f->name) + 1;
1443       /* Allocate u->dir off stack, but reallocate only if a larger
1444          string is needed.  */
1445       if (len > current_length)
1446         current_container = (char *)alloca (len);
1447       u->dir = current_container;
1448       /* When retrieving recursively, all directories must be
1449          absolute.  This restriction will (hopefully!) be lifted in
1450          the future.  */
1451       sprintf (u->dir, "/%s%s%s", odir + (*odir == '/'),
1452               (!*odir || (*odir == '/' && !* (odir + 1))) ? "" : "/", f->name);
1453       if (!accdir (u->dir, ALLABS))
1454         {
1455           logprintf (LOG_VERBOSE, _("\
1456 Not descending to `%s' as it is excluded/not-included.\n"), u->dir);
1457           u->dir = odir;
1458           continue;
1459         }
1460       con->st &= ~DONE_CWD;
1461       ftp_retrieve_glob (u, con, GETALL);
1462       /* Set the time-stamp?  */
1463       u->dir = odir;
1464     }
1465   if (opt.quota && opt.downloaded > opt.quota)
1466     return QUOTEXC;
1467   else
1468     return RETROK;
1469 }
1470
1471
1472 /* A near-top-level function to retrieve the files in a directory.
1473    The function calls ftp_get_listing, to get a linked list of files.
1474    Then it weeds out the file names that do not match the pattern.
1475    ftp_retrieve_list is called with this updated list as an argument.
1476
1477    If the argument ACTION is GETONE, just download the file (but first
1478    get the listing, so that the time-stamp is heeded); if it's GLOBALL,
1479    use globbing; if it's GETALL, download the whole directory.  */
1480 static uerr_t
1481 ftp_retrieve_glob (struct urlinfo *u, ccon *con, int action)
1482 {
1483   struct fileinfo *orig, *start;
1484   uerr_t res;
1485
1486   con->cmd |= LEAVE_PENDING;
1487
1488   orig = ftp_get_listing (u, con);
1489   start = orig;
1490   /* First: weed out that do not conform the global rules given in
1491      opt.accepts and opt.rejects.  */
1492   if (opt.accepts || opt.rejects)
1493     {
1494       struct fileinfo *f = orig;
1495
1496       while (f)
1497         {
1498           if (f->type != FT_DIRECTORY && !acceptable (f->name))
1499             {
1500               logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"), f->name);
1501               f = delelement (f, &start);
1502             }
1503           else
1504             f = f->next;
1505         }
1506     }
1507   /* Now weed out the files that do not match our globbing pattern.
1508      If we are dealing with a globbing pattern, that is.  */
1509   if (*u->file && (action == GLOBALL || action == GETONE))
1510     {
1511       int matchres = 0;
1512       struct fileinfo *f = start;
1513
1514       while (f)
1515         {
1516           matchres = fnmatch (u->file, f->name, 0);
1517           if (matchres == -1)
1518             {
1519               logprintf (LOG_NOTQUIET, "%s: %s\n", u->local,
1520                          strerror (errno));
1521               break;
1522             }
1523           if (matchres == FNM_NOMATCH)
1524             f = delelement (f, &start); /* delete the element from the list */
1525           else
1526             f = f->next;        /* leave the element in the list */
1527         }
1528       if (matchres == -1)
1529         {
1530           freefileinfo (start);
1531           return RETRBADPATTERN;
1532         }
1533     }
1534   res = RETROK;
1535   if (start)
1536     {
1537       /* Just get everything.  */
1538       ftp_retrieve_list (u, start, con);
1539     }
1540   else if (!start)
1541     {
1542       if (action == GLOBALL)
1543         {
1544           /* No luck.  */
1545           /* #### This message SUCKS.  We should see what was the
1546              reason that nothing was retrieved.  */
1547           logprintf (LOG_VERBOSE, _("No matches on pattern `%s'.\n"), u->file);
1548         }
1549       else /* GETONE or GETALL */
1550         {
1551           /* Let's try retrieving it anyway.  */
1552           con->st |= ON_YOUR_OWN;
1553           res = ftp_loop_internal (u, NULL, con);
1554           return res;
1555         }
1556     }
1557   freefileinfo (start);
1558   if (downloaded_exceeds_quota ())
1559     return QUOTEXC;
1560   else
1561     /* #### Should we return `res' here?  */
1562     return RETROK;
1563 }
1564
1565 /* The wrapper that calls an appropriate routine according to contents
1566    of URL.  Inherently, its capabilities are limited on what can be
1567    encoded into a URL.  */
1568 uerr_t
1569 ftp_loop (struct urlinfo *u, int *dt)
1570 {
1571   ccon con;                     /* FTP connection */
1572   uerr_t res;
1573
1574   *dt = 0;
1575
1576   rbuf_uninitialize (&con.rbuf);
1577   con.st = ON_YOUR_OWN;
1578   res = RETROK;                 /* in case it's not used */
1579
1580   /* If the file name is empty, the user probably wants a directory
1581      index.  We'll provide one, properly HTML-ized.  Unless
1582      opt.htmlify is 0, of course.  :-) */
1583   if (!*u->file && !opt.recursive)
1584     {
1585       struct fileinfo *f = ftp_get_listing (u, &con);
1586
1587       if (f)
1588         {
1589           if (opt.htmlify)
1590             {
1591               char *filename = (opt.output_document
1592                                 ? xstrdup (opt.output_document)
1593                                 : (u->local ? xstrdup (u->local)
1594                                    : url_filename (u)));
1595               res = ftp_index (filename, u, f);
1596               if (res == FTPOK && opt.verbose)
1597                 {
1598                   if (!opt.output_document)
1599                     {
1600                       struct stat st;
1601                       long sz;
1602                       if (stat (filename, &st) == 0)
1603                         sz = st.st_size;
1604                       else
1605                         sz = -1;
1606                       logprintf (LOG_NOTQUIET,
1607                                  _("Wrote HTML-ized index to `%s' [%ld].\n"),
1608                                  filename, sz);
1609                     }
1610                   else
1611                     logprintf (LOG_NOTQUIET,
1612                                _("Wrote HTML-ized index to `%s'.\n"),
1613                                filename);
1614                 }
1615               xfree (filename);
1616             }
1617           freefileinfo (f);
1618         }
1619     }
1620   else
1621     {
1622       int wild = has_wildcards_p (u->file);
1623       if ((opt.ftp_glob && wild) || opt.recursive || opt.timestamping)
1624         {
1625           /* ftp_retrieve_glob is a catch-all function that gets called
1626              if we need globbing, time-stamping or recursion.  Its
1627              third argument is just what we really need.  */
1628           ftp_retrieve_glob (u, &con,
1629                              (opt.ftp_glob && wild) ? GLOBALL : GETONE);
1630         }
1631       else
1632         res = ftp_loop_internal (u, NULL, &con);
1633     }
1634   if (res == FTPOK)
1635     res = RETROK;
1636   if (res == RETROK)
1637     *dt |= RETROKF;
1638   /* If a connection was left, quench it.  */
1639   if (rbuf_initialized_p (&con.rbuf))
1640     CLOSE (RBUF_FD (&con.rbuf));
1641   FREE_MAYBE (pwd);
1642   pwd = NULL;
1643   return res;
1644 }
1645
1646 /* Delete an element from the fileinfo linked list.  Returns the
1647    address of the next element, or NULL if the list is exhausted.  It
1648    can modify the start of the list.  */
1649 static struct fileinfo *
1650 delelement (struct fileinfo *f, struct fileinfo **start)
1651 {
1652   struct fileinfo *prev = f->prev;
1653   struct fileinfo *next = f->next;
1654
1655   xfree (f->name);
1656   FREE_MAYBE (f->linkto);
1657   xfree (f);
1658
1659   if (next)
1660     next->prev = prev;
1661   if (prev)
1662     prev->next = next;
1663   else
1664     *start = next;
1665   return next;
1666 }
1667
1668 /* Free the fileinfo linked list of files.  */
1669 static void
1670 freefileinfo (struct fileinfo *f)
1671 {
1672   while (f)
1673     {
1674       struct fileinfo *next = f->next;
1675       xfree (f->name);
1676       if (f->linkto)
1677         xfree (f->linkto);
1678       xfree (f);
1679       f = next;
1680     }
1681 }