1 /* File Transfer Protocol support.
2 Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
4 This file is part of Wget.
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.
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.
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. */
32 #include <sys/types.h>
36 # include <netdb.h> /* for h_errno */
59 /* File where the "ls -al" listing will be saved. */
60 #define LIST_FILENAME ".listing"
62 extern char ftp_last_respline[];
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
68 ftp_expected_bytes (const char *s)
74 while (*s && *s != '(')
78 for (++s; *s && ISSPACE (*s); s++);
86 res = (*s - '0') + 10 * res;
89 while (*s && ISDIGIT (*s));
92 while (*s && ISSPACE (*s))
96 if (TOLOWER (*s) != 'b')
98 if (strncasecmp (s, "byte", 4))
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. */
110 getftp (struct urlinfo *u, long *len, long restval, ccon *con)
112 int csock, dtsock, res;
115 char *user, *passwd, *respline;
117 unsigned char pasv_addr[6];
119 int passive_mode_open = 0;
120 long expected_bytes = 0L;
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
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);
133 search_netrc (u->host, (const char **)&user, (const char **)&passwd, 1);
134 user = user ? user : opt.ftp_acc;
136 opt.ftp_pass = ftp_getaddress ();
137 passwd = passwd ? passwd : opt.ftp_pass;
138 assert (user && passwd);
143 if (!(cmd & DO_LOGIN))
144 csock = RBUF_FD (&con->rbuf);
145 else /* cmd & DO_LOGIN */
147 /* Login to the server: */
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);
155 rbuf_uninitialize (&con->rbuf);
158 /* Do not close the socket in first several cases, since it
159 wasn't created at all. */
161 logputs (LOG_VERBOSE, "\n");
162 logprintf (LOG_NOTQUIET, "%s: %s\n", u->host, herrmsg (h_errno));
166 logputs (LOG_VERBOSE, "\n");
167 logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
171 logputs (LOG_VERBOSE, "\n");
172 logprintf (LOG_NOTQUIET, _("Connection to %s:%hu refused.\n"),
175 rbuf_uninitialize (&con->rbuf);
178 logputs (LOG_VERBOSE, "\n");
179 logprintf (LOG_NOTQUIET, "connect: %s\n", strerror (errno));
181 rbuf_uninitialize (&con->rbuf);
188 /* Since this is a new connection, we may safely discard
189 anything left in the buffer. */
190 rbuf_discard (&con->rbuf);
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 */
202 logputs (LOG_VERBOSE, "\n");
203 logputs (LOG_NOTQUIET, _("\
204 Error in server response, closing control connection.\n"));
206 rbuf_uninitialize (&con->rbuf);
210 logputs (LOG_VERBOSE, "\n");
211 logputs (LOG_NOTQUIET, _("Error in server greeting.\n"));
213 rbuf_uninitialize (&con->rbuf);
217 logputs (LOG_VERBOSE, "\n");
218 logputs (LOG_NOTQUIET,
219 _("Write failed, closing control connection.\n"));
221 rbuf_uninitialize (&con->rbuf);
225 logputs (LOG_VERBOSE, "\n");
226 logputs (LOG_NOTQUIET, _("The server refuses login.\n"));
228 rbuf_uninitialize (&con->rbuf);
229 return FTPLOGREFUSED;
232 logputs (LOG_VERBOSE, "\n");
233 logputs (LOG_NOTQUIET, _("Login incorrect.\n"));
235 rbuf_uninitialize (&con->rbuf);
239 if (!opt.server_response)
240 logputs (LOG_VERBOSE, _("Logged in!\n"));
247 /* Third: Get the system type */
248 if (!opt.server_response)
249 logprintf (LOG_VERBOSE, "==> SYST ... ");
250 err = ftp_syst (&con->rbuf, &con->rs);
255 logputs (LOG_VERBOSE, "\n");
256 logputs (LOG_NOTQUIET, _("\
257 Error in server response, closing control connection.\n"));
259 rbuf_uninitialize (&con->rbuf);
263 logputs (LOG_VERBOSE, "\n");
264 logputs (LOG_NOTQUIET,
265 _("Server error, can't determine system type.\n"));
268 /* Everything is OK. */
274 if (!opt.server_response)
275 logputs (LOG_VERBOSE, _("done. "));
277 /* Fourth: Find the initial ftp directory */
279 if (!opt.server_response)
280 logprintf (LOG_VERBOSE, "==> PWD ... ");
281 err = ftp_pwd(&con->rbuf, &con->id);
285 case FTPRERR || FTPSRVERR :
286 logputs (LOG_VERBOSE, "\n");
287 logputs (LOG_NOTQUIET, _("\
288 Error in server response, closing control connection.\n"));
290 rbuf_uninitialize (&con->rbuf);
294 /* Everything is OK. */
300 if (!opt.server_response)
301 logputs (LOG_VERBOSE, _("done.\n"));
303 /* Fifth: Set the FTP type. */
304 if (!opt.server_response)
305 logprintf (LOG_VERBOSE, "==> TYPE %c ... ", TOUPPER (u->ftp_type));
306 err = ftp_type (&con->rbuf, TOUPPER (u->ftp_type));
307 /* FTPRERR, WRITEFAILED, FTPUNKNOWNTYPE */
311 logputs (LOG_VERBOSE, "\n");
312 logputs (LOG_NOTQUIET, _("\
313 Error in server response, closing control connection.\n"));
315 rbuf_uninitialize (&con->rbuf);
319 logputs (LOG_VERBOSE, "\n");
320 logputs (LOG_NOTQUIET,
321 _("Write failed, closing control connection.\n"));
323 rbuf_uninitialize (&con->rbuf);
327 logputs (LOG_VERBOSE, "\n");
328 logprintf (LOG_NOTQUIET,
329 _("Unknown type `%c', closing control connection.\n"),
330 TOUPPER (u->ftp_type));
332 rbuf_uninitialize (&con->rbuf);
335 /* Everything is OK. */
341 if (!opt.server_response)
342 logputs (LOG_VERBOSE, _("done. "));
348 logputs (LOG_VERBOSE, _("==> CWD not needed.\n"));
351 /* Change working directory. If the FTP host runs VMS and
352 the path specified is absolute, we will have to convert
353 it to VMS style as VMS does not like leading slashes */
354 DEBUGP (("changing working directory\n"));
355 if (*(u->dir) == '/')
357 int pwd_len = strlen (con->id);
358 char *result = (char *)alloca (strlen (u->dir) + pwd_len + 10);
364 char *tmp_dir, *tmpp;
365 STRDUP_ALLOCA (tmp_dir, u->dir);
366 for (tmpp = tmp_dir; *tmpp; tmpp++)
369 strcpy (result, con->id);
370 /* pwd ends with ']', we have to get rid of it */
371 result[pwd_len - 1]= '\0';
372 strcat (result, tmp_dir);
373 strcat (result, "]");
379 /* pwd_len == 1 means pwd = "/", but u->dir begins with '/'
382 strcpy (result, con->id);
383 strcat (result, u->dir);
384 DEBUGP(("\npwd=\"%s\"", con->id));
385 DEBUGP(("\nu->dir=\"%s\"", u->dir));
391 if (!opt.server_response)
392 logprintf (LOG_VERBOSE, "==> CWD %s ... ", result);
393 err = ftp_cwd (&con->rbuf, result);
397 if (!opt.server_response)
398 logprintf (LOG_VERBOSE, "==> CWD %s ... ", u->dir);
399 err = ftp_cwd (&con->rbuf, u->dir);
401 /* FTPRERR, WRITEFAILED, FTPNSFOD */
405 logputs (LOG_VERBOSE, "\n");
406 logputs (LOG_NOTQUIET, _("\
407 Error in server response, closing control connection.\n"));
409 rbuf_uninitialize (&con->rbuf);
413 logputs (LOG_VERBOSE, "\n");
414 logputs (LOG_NOTQUIET,
415 _("Write failed, closing control connection.\n"));
417 rbuf_uninitialize (&con->rbuf);
421 logputs (LOG_VERBOSE, "\n");
422 logprintf (LOG_NOTQUIET, _("No such directory `%s'.\n\n"),
425 rbuf_uninitialize (&con->rbuf);
435 if (!opt.server_response)
436 logputs (LOG_VERBOSE, _("done.\n"));
439 else /* do not CWD */
440 logputs (LOG_VERBOSE, _("==> CWD not required.\n"));
442 /* If anything is to be retrieved, PORT (or PASV) must be sent. */
443 if (cmd & (DO_LIST | DO_RETR))
445 if (opt.ftp_pasv > 0)
448 unsigned short tport;
450 if (!opt.server_response)
451 logputs (LOG_VERBOSE, "==> PASV ... ");
452 err = ftp_pasv (&con->rbuf, pasv_addr);
453 /* FTPRERR, WRITEFAILED, FTPNOPASV, FTPINVPASV */
457 logputs (LOG_VERBOSE, "\n");
458 logputs (LOG_NOTQUIET, _("\
459 Error in server response, closing control connection.\n"));
461 rbuf_uninitialize (&con->rbuf);
465 logputs (LOG_VERBOSE, "\n");
466 logputs (LOG_NOTQUIET,
467 _("Write failed, closing control connection.\n"));
469 rbuf_uninitialize (&con->rbuf);
473 logputs (LOG_VERBOSE, "\n");
474 logputs (LOG_NOTQUIET, _("Cannot initiate PASV transfer.\n"));
477 logputs (LOG_VERBOSE, "\n");
478 logputs (LOG_NOTQUIET, _("Cannot parse PASV response.\n"));
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);
496 /* Do not close the socket in first several cases,
497 since it wasn't created at all. */
499 logputs (LOG_VERBOSE, "\n");
500 logprintf (LOG_NOTQUIET, "%s: %s\n", thost,
503 rbuf_uninitialize (&con->rbuf);
507 logputs (LOG_VERBOSE, "\n");
508 logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
510 rbuf_uninitialize (&con->rbuf);
514 logputs (LOG_VERBOSE, "\n");
515 logprintf (LOG_NOTQUIET,
516 _("Connection to %s:%hu refused.\n"),
519 rbuf_uninitialize (&con->rbuf);
523 logputs (LOG_VERBOSE, "\n");
524 logprintf (LOG_NOTQUIET, "connect: %s\n",
527 rbuf_uninitialize (&con->rbuf);
535 passive_mode_open= 1; /* Flag to avoid accept port */
536 if (!opt.server_response)
537 logputs (LOG_VERBOSE, _("done. "));
541 if (!passive_mode_open) /* Try to use a port command if PASV failed */
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 */
551 logputs (LOG_VERBOSE, "\n");
552 logputs (LOG_NOTQUIET, _("\
553 Error in server response, closing control connection.\n"));
556 rbuf_uninitialize (&con->rbuf);
560 logputs (LOG_VERBOSE, "\n");
561 logputs (LOG_NOTQUIET,
562 _("Write failed, closing control connection.\n"));
565 rbuf_uninitialize (&con->rbuf);
569 logputs (LOG_VERBOSE, "\n");
570 logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
573 rbuf_uninitialize (&con->rbuf);
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"),
585 logputs (LOG_VERBOSE, "\n");
586 logprintf (LOG_NOTQUIET, "%s: %s\n", u->host,
590 rbuf_uninitialize (&con->rbuf);
594 logputs (LOG_VERBOSE, "\n");
595 logputs (LOG_NOTQUIET, _("Invalid PORT.\n"));
598 rbuf_uninitialize (&con->rbuf);
608 if (!opt.server_response)
609 logputs (LOG_VERBOSE, _("done. "));
611 } /* cmd & (DO_LIST | DO_RETR) */
613 /* Restart if needed. */
614 if (restval && (cmd & DO_RETR))
616 if (!opt.server_response)
617 logprintf (LOG_VERBOSE, "==> REST %ld ... ", restval);
618 err = ftp_rest (&con->rbuf, restval);
620 /* FTPRERR, WRITEFAILED, FTPRESTFAIL */
624 logputs (LOG_VERBOSE, "\n");
625 logputs (LOG_NOTQUIET, _("\
626 Error in server response, closing control connection.\n"));
629 rbuf_uninitialize (&con->rbuf);
633 logputs (LOG_VERBOSE, "\n");
634 logputs (LOG_NOTQUIET,
635 _("Write failed, closing control connection.\n"));
638 rbuf_uninitialize (&con->rbuf);
642 logputs (LOG_VERBOSE, _("\nREST failed, starting from scratch.\n"));
652 if (err != FTPRESTFAIL && !opt.server_response)
653 logputs (LOG_VERBOSE, _("done. "));
654 } /* restval && cmd & DO_RETR */
660 if (!opt.server_response)
663 logputs (LOG_VERBOSE, "\n");
664 logprintf (LOG_VERBOSE, "==> RETR %s ... ", u->file);
667 err = ftp_retr (&con->rbuf, u->file);
668 /* FTPRERR, WRITEFAILED, FTPNSFOD */
672 logputs (LOG_VERBOSE, "\n");
673 logputs (LOG_NOTQUIET, _("\
674 Error in server response, closing control connection.\n"));
677 rbuf_uninitialize (&con->rbuf);
681 logputs (LOG_VERBOSE, "\n");
682 logputs (LOG_NOTQUIET,
683 _("Write failed, closing control connection.\n"));
686 rbuf_uninitialize (&con->rbuf);
690 logputs (LOG_VERBOSE, "\n");
691 logprintf (LOG_NOTQUIET, _("No such file `%s'.\n\n"), u->file);
703 if (!opt.server_response)
704 logputs (LOG_VERBOSE, _("done.\n"));
705 expected_bytes = ftp_expected_bytes (ftp_last_respline);
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
715 err = ftp_list (&con->rbuf, NULL);
716 /* FTPRERR, WRITEFAILED */
720 logputs (LOG_VERBOSE, "\n");
721 logputs (LOG_NOTQUIET, _("\
722 Error in server response, closing control connection.\n"));
725 rbuf_uninitialize (&con->rbuf);
729 logputs (LOG_VERBOSE, "\n");
730 logputs (LOG_NOTQUIET,
731 _("Write failed, closing control connection.\n"));
734 rbuf_uninitialize (&con->rbuf);
738 logputs (LOG_VERBOSE, "\n");
739 logprintf (LOG_NOTQUIET, _("No such file or directory `%s'.\n\n"),
751 if (!opt.server_response)
752 logputs (LOG_VERBOSE, _("done.\n"));
753 expected_bytes = ftp_expected_bytes (ftp_last_respline);
754 } /* cmd & DO_LIST */
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))
761 DEBUGP (("Lying FTP server found, adjusting.\n"));
762 expected_bytes = *len;
765 /* If no transmission was required, then everything is OK. */
766 if (!(cmd & (DO_LIST | DO_RETR)))
769 if (!passive_mode_open) /* we are not using pasive mode so we need
772 /* Open the data transmission socket by calling acceptport(). */
773 err = acceptport (&dtsock);
774 /* Possible errors: ACCEPTERR. */
775 if (err == ACCEPTERR)
777 logprintf (LOG_NOTQUIET, "accept: %s\n", strerror (errno));
782 /* Open the file -- if opt.dfp is set, use it instead. */
783 if (!opt.dfp || con->cmd & DO_LIST)
785 mkalldirs (u->local);
787 rotate_backups (u->local);
788 /* #### Is this correct? */
789 chmod (u->local, 0600);
791 fp = fopen (u->local, restval ? "ab" : "wb");
794 logprintf (LOG_NOTQUIET, "%s: %s\n", u->local, strerror (errno));
796 rbuf_uninitialize (&con->rbuf);
806 /* This will silently fail for streams that don't correspond
807 to regular files, but that's OK. */
815 logprintf (LOG_VERBOSE, _("Length: %s"), legible (*len));
817 logprintf (LOG_VERBOSE, _(" [%s to go]"), legible (*len - restval));
818 logputs (LOG_VERBOSE, "\n");
820 else if (expected_bytes)
822 logprintf (LOG_VERBOSE, _("Length: %s"), legible (expected_bytes));
824 logprintf (LOG_VERBOSE, _(" [%s to go]"),
825 legible (expected_bytes - restval));
826 logputs (LOG_VERBOSE, _(" (unauthoritative)\n"));
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, 0);
834 /* Close data connection socket. */
836 /* Close the local file. */
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! */
842 if (!opt.dfp || con->cmd & DO_LIST)
843 flush_res = fclose (fp);
845 flush_res = fflush (fp);
846 if (flush_res == EOF)
849 /* If get_contents couldn't write to fp, bail out. */
852 logprintf (LOG_NOTQUIET, _("%s: %s, closing control connection.\n"),
853 u->local, strerror (errno));
855 rbuf_uninitialize (&con->rbuf);
860 logprintf (LOG_NOTQUIET, _("%s (%s) - Data connection: %s; "),
861 tms, tmrate, strerror (errno));
862 if (opt.server_response)
863 logputs (LOG_ALWAYS, "\n");
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);
873 /* The control connection is decidedly closed. Print the time
874 only if it hasn't already been printed. */
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). */
883 rbuf_uninitialize (&con->rbuf);
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')
894 logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
895 logputs (LOG_NOTQUIET, _("Data transfer aborted.\n"));
902 /* What now? The data connection was erroneous, whereas the
903 response says everything is OK. We shall play it safe. */
907 if (!(cmd & LEAVE_PENDING))
909 /* I should probably send 'QUIT' and check for a reply, but this
910 is faster. #### Is it OK, though? */
912 rbuf_uninitialize (&con->rbuf);
914 /* If it was a listing, and opt.server_response is true,
916 if (opt.server_response && (con->cmd & DO_LIST))
918 mkalldirs (u->local);
919 fp = fopen (u->local, "r");
921 logprintf (LOG_ALWAYS, "%s: %s\n", u->local, strerror (errno));
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)))
929 logprintf (LOG_ALWAYS, "%s\n", line);
934 } /* con->cmd & DO_LIST && server_response */
939 /* A one-file FTP loop. This is the part where FTP retrieval is
940 retried, and retried, and retried, and...
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. */
945 ftp_loop_internal (struct urlinfo *u, struct fileinfo *f, ccon *con)
949 char *tms, *tmrate, *locf;
954 u->local = url_filename (u);
956 if (opt.noclobber && file_exists_p (u->local))
958 logprintf (LOG_VERBOSE,
959 _("File `%s' already there, not retrieving.\n"), u->local);
960 /* If the file is there, we suppose it's retrieved OK. */
964 /* Remove it if it's a link. */
965 remove_link (u->local);
966 if (!opt.output_document)
969 locf = opt.output_document;
973 if (con->st & ON_YOUR_OWN)
974 con->st = ON_YOUR_OWN;
976 orig_lp = con->cmd & LEAVE_PENDING ? 1 : 0;
981 /* Increment the pass counter. */
983 sleep_between_retrievals (count);
984 if (con->st & ON_YOUR_OWN)
987 con->cmd |= (DO_RETR | LEAVE_PENDING);
988 if (rbuf_initialized_p (&con->rbuf))
989 con->cmd &= ~ (DO_LOGIN | DO_CWD);
991 con->cmd |= (DO_LOGIN | DO_CWD);
993 else /* not on your own */
995 if (rbuf_initialized_p (&con->rbuf))
996 con->cmd &= ~DO_LOGIN;
998 con->cmd |= DO_LOGIN;
999 if (con->st & DONE_CWD)
1000 con->cmd &= ~DO_CWD;
1004 /* Assume no restarting. */
1006 if ((count > 1 || opt.always_rest)
1007 && !(con->cmd & DO_LIST)
1008 && file_exists_p (u->local))
1009 if (stat (u->local, &st) == 0)
1010 restval = st.st_size;
1011 /* Get the current time string. */
1012 tms = time_str (NULL);
1013 /* Print fetch message, if opt.verbose. */
1016 char *hurl = str_url (u->proxy ? u->proxy : u, 1);
1020 sprintf (tmp, _("(try:%2d)"), count);
1021 logprintf (LOG_VERBOSE, "--%s-- %s\n %s => `%s'\n",
1022 tms, hurl, tmp, locf);
1024 ws_changetitle (hurl, 1);
1028 /* Send getftp the proper length, if fileinfo was provided. */
1033 err = getftp (u, &len, restval, con);
1035 tms = time_str (NULL);
1036 tmrate = rate (len - restval, con->dltime, 0);
1038 if (!rbuf_initialized_p (&con->rbuf))
1039 con->st &= ~DONE_CWD;
1041 con->st |= DONE_CWD;
1045 case HOSTERR: case CONREFUSED: case FWRITEERR: case FOPENERR:
1046 case FTPNSFOD: case FTPLOGINC: case FTPNOPASV:
1047 /* Fatal errors, give up. */
1050 case CONSOCKERR: case CONERROR: case FTPSRVERR: case FTPRERR:
1051 case WRITEFAILED: case FTPUNKNOWNTYPE: case CONPORTERR:
1052 case BINDERR: case LISTENERR: case ACCEPTERR:
1053 case FTPPORTERR: case FTPLOGREFUSED: case FTPINVPASV:
1054 printwhat (count, opt.ntry);
1055 /* non-fatal errors */
1059 /* If the control connection was closed, the retrieval
1060 will be considered OK if f->size == len. */
1061 if (!f || len != f->size)
1063 printwhat (count, opt.ntry);
1075 /* If we get out of the switch above without continue'ing, we've
1076 successfully downloaded a file. Remember this fact. */
1077 downloaded_file(FILE_DOWNLOADED_NORMALLY, locf);
1079 if (con->st & ON_YOUR_OWN)
1081 CLOSE (RBUF_FD (&con->rbuf));
1082 rbuf_uninitialize (&con->rbuf);
1084 logprintf (LOG_VERBOSE, _("%s (%s) - `%s' saved [%ld]\n\n"),
1085 tms, tmrate, locf, len);
1086 if (!opt.verbose && !opt.quiet)
1088 /* Need to hide the password from the URL. The `if' is here
1089 so that we don't do the needless allocation every
1091 char *hurl = str_url (u->proxy ? u->proxy : u, 1);
1092 logprintf (LOG_NONVERBOSE, "%s URL: %s [%ld] -> \"%s\" [%d]\n",
1093 tms, hurl, len, locf, count);
1097 if ((con->cmd & DO_LIST))
1098 /* This is a directory listing file. */
1100 if (!opt.remove_listing)
1101 /* --dont-remove-listing was specified, so do count this towards the
1102 number of bytes and files downloaded. */
1104 downloaded_increase (len);
1108 /* Deletion of listing files is not controlled by --delete-after, but
1109 by the more specific option --dont-remove-listing, and the code
1110 to do this deletion is in another function. */
1113 /* This is not a directory listing file. */
1115 /* Unlike directory listing files, don't pretend normal files weren't
1116 downloaded if they're going to be deleted. People seeding proxies,
1117 for instance, may want to know how many bytes and files they've
1118 downloaded through it. */
1119 downloaded_increase (len);
1122 if (opt.delete_after)
1124 DEBUGP (("Removing file due to --delete-after in"
1125 " ftp_loop_internal():\n"));
1126 logprintf (LOG_VERBOSE, _("Removing %s.\n"), locf);
1128 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1132 /* Restore the original leave-pendingness. */
1134 con->cmd |= LEAVE_PENDING;
1136 con->cmd &= ~LEAVE_PENDING;
1138 } while (!opt.ntry || (count < opt.ntry));
1140 if (rbuf_initialized_p (&con->rbuf) && (con->st & ON_YOUR_OWN))
1142 CLOSE (RBUF_FD (&con->rbuf));
1143 rbuf_uninitialize (&con->rbuf);
1148 /* Return the directory listing in a reusable format. The directory
1149 is specifed in u->dir. */
1150 static struct fileinfo *
1151 ftp_get_listing (struct urlinfo *u, ccon *con)
1155 char *olocal = u->local;
1156 char *list_filename, *ofile;
1158 con->st &= ~ON_YOUR_OWN;
1159 con->cmd |= (DO_LIST | LEAVE_PENDING);
1160 con->cmd &= ~DO_RETR;
1161 /* Get the listing filename. */
1163 u->file = LIST_FILENAME;
1164 list_filename = url_filename (u);
1166 u->local = list_filename;
1167 DEBUGP ((_("Using `%s' as listing tmp file.\n"), list_filename));
1168 err = ftp_loop_internal (u, NULL, con);
1171 f = ftp_parse_ls (list_filename, con->rs);
1174 if (opt.remove_listing)
1176 if (unlink (list_filename))
1177 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1179 logprintf (LOG_VERBOSE, _("Removed `%s'.\n"), list_filename);
1181 xfree (list_filename);
1182 con->cmd &= ~DO_LIST;
1186 static uerr_t ftp_retrieve_dirs PARAMS ((struct urlinfo *, struct fileinfo *,
1188 static uerr_t ftp_retrieve_glob PARAMS ((struct urlinfo *, ccon *, int));
1189 static struct fileinfo *delelement PARAMS ((struct fileinfo *,
1190 struct fileinfo **));
1191 static void freefileinfo PARAMS ((struct fileinfo *f));
1193 /* Retrieve a list of files given in struct fileinfo linked list. If
1194 a file is a symbolic link, do not retrieve it, but rather try to
1195 set up a similar link on the local disk, if the symlinks are
1198 If opt.recursive is set, after all files have been retrieved,
1199 ftp_retrieve_dirs will be called to retrieve the directories. */
1201 ftp_retrieve_list (struct urlinfo *u, struct fileinfo *f, ccon *con)
1203 static int depth = 0;
1205 char *olocal, *ofile;
1206 struct fileinfo *orig;
1211 /* Increase the depth. */
1213 if (opt.reclevel != INFINITE_RECURSION && depth > opt.reclevel)
1215 DEBUGP ((_("Recursion depth %d exceeded max. depth %d.\n"),
1216 depth, opt.reclevel));
1224 con->st &= ~ON_YOUR_OWN;
1225 if (!(con->st & DONE_CWD))
1228 con->cmd &= ~DO_CWD;
1229 con->cmd |= (DO_RETR | LEAVE_PENDING);
1231 if (!rbuf_initialized_p (&con->rbuf))
1232 con->cmd |= DO_LOGIN;
1234 con->cmd &= ~DO_LOGIN;
1236 err = RETROK; /* in case it's not used */
1240 if (downloaded_exceeds_quota ())
1248 u->local = url_filename (u);
1252 if (opt.timestamping && f->type == FT_PLAINFILE)
1255 /* If conversion of HTML files retrieved via FTP is ever implemented,
1256 we'll need to stat() <file>.orig here when -K has been specified.
1257 I'm not implementing it now since files on an FTP server are much
1258 more likely than files on an HTTP server to legitimately have a
1260 if (!stat (u->local, &st))
1264 /* Else, get it from the file. */
1265 local_size = st.st_size;
1267 /* Compare file sizes only for servers that tell us correct
1268 values. Assumme sizes being equal for servers that lie
1270 cor_val = (con->rs == ST_UNIX || con->rs == ST_WINNT);
1271 eq_size = cor_val ? (local_size == f->size) : 1 ;
1272 if (f->tstamp <= tml && eq_size)
1274 /* Remote file is older, file sizes can be compared and
1276 logprintf (LOG_VERBOSE, _("\
1277 Remote file no newer than local file `%s' -- not retrieving.\n"), u->local);
1282 /* Remote file is newer or sizes cannot be matched */
1283 logprintf (LOG_VERBOSE, _("\
1284 Remote file is newer than local file `%s' -- retrieving.\n\n"),
1289 /* Sizes do not match */
1290 logprintf (LOG_VERBOSE, _("\
1291 The sizes do not match (local %ld) -- retrieving.\n\n"), local_size);
1294 } /* opt.timestamping && f->type == FT_PLAINFILE */
1298 /* If opt.retr_symlinks is defined, we treat symlinks as
1299 if they were normal files. There is currently no way
1300 to distinguish whether they might be directories, and
1302 if (!opt.retr_symlinks)
1306 logputs (LOG_NOTQUIET,
1307 _("Invalid name of the symlink, skipping.\n"));
1311 /* Check whether we already have the correct
1313 int rc = lstat (u->local, &st);
1316 size_t len = strlen (f->linkto) + 1;
1317 if (S_ISLNK (st.st_mode))
1319 char *link_target = (char *)alloca (len);
1320 size_t n = readlink (u->local, link_target, len);
1322 && (memcmp (link_target, f->linkto, n) == 0))
1324 logprintf (LOG_VERBOSE, _("\
1325 Already have correct symlink %s -> %s\n\n"),
1326 u->local, f->linkto);
1332 logprintf (LOG_VERBOSE, _("Creating symlink %s -> %s\n"),
1333 u->local, f->linkto);
1334 /* Unlink before creating symlink! */
1336 if (symlink (f->linkto, u->local) == -1)
1337 logprintf (LOG_NOTQUIET, "symlink: %s\n",
1339 logputs (LOG_VERBOSE, "\n");
1340 } /* have f->linkto */
1341 #else /* not HAVE_SYMLINK */
1342 logprintf (LOG_NOTQUIET,
1343 _("Symlinks not supported, skipping symlink `%s'.\n"),
1345 #endif /* not HAVE_SYMLINK */
1347 else /* opt.retr_symlinks */
1350 err = ftp_loop_internal (u, f, con);
1351 } /* opt.retr_symlinks */
1355 logprintf (LOG_NOTQUIET, _("Skipping directory `%s'.\n"),
1359 /* Call the retrieve loop. */
1361 err = ftp_loop_internal (u, f, con);
1364 logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
1369 /* Set the time-stamp information to the local file. Symlinks
1370 are not to be stamped because it sets the stamp on the
1372 if (!(f->type == FT_SYMLINK && !opt.retr_symlinks)
1375 && file_exists_p (u->local))
1377 /* #### This code repeats in http.c and ftp.c. Move it to a
1379 const char *fl = NULL;
1380 if (opt.output_document)
1382 if (opt.od_known_regular)
1383 fl = opt.output_document;
1388 touch (fl, f->tstamp);
1390 else if (f->tstamp == -1)
1391 logprintf (LOG_NOTQUIET, _("%s: corrupt time-stamp.\n"), u->local);
1393 if (f->perms && f->type == FT_PLAINFILE && dlthis)
1394 chmod (u->local, f->perms);
1396 DEBUGP (("Unrecognized permissions for %s.\n", u->local));
1401 /* Break on fatals. */
1402 if (err == QUOTEXC || err == HOSTERR || err == FWRITEERR)
1404 con->cmd &= ~ (DO_CWD | DO_LOGIN);
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));
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. */
1423 ftp_retrieve_dirs (struct urlinfo *u, struct fileinfo *f, ccon *con)
1426 char *current_container = NULL;
1427 int current_length = 0;
1429 for (; f; f = f->next)
1433 if (downloaded_exceeds_quota ())
1435 if (f->type != FT_DIRECTORY)
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 sprintf (u->dir, "/%s%s%s", odir + (*odir == '/'),
1445 (!*odir || (*odir == '/' && !* (odir + 1))) ? "" : "/", f->name);
1446 if (!accdir (u->dir, ALLABS))
1448 logprintf (LOG_VERBOSE, _("\
1449 Not descending to `%s' as it is excluded/not-included.\n"), u->dir);
1453 con->st &= ~DONE_CWD;
1454 ftp_retrieve_glob (u, con, GETALL);
1455 /* Set the time-stamp? */
1458 if (opt.quota && opt.downloaded > opt.quota)
1465 /* A near-top-level function to retrieve the files in a directory.
1466 The function calls ftp_get_listing, to get a linked list of files.
1467 Then it weeds out the file names that do not match the pattern.
1468 ftp_retrieve_list is called with this updated list as an argument.
1470 If the argument ACTION is GETONE, just download the file (but first
1471 get the listing, so that the time-stamp is heeded); if it's GLOBALL,
1472 use globbing; if it's GETALL, download the whole directory. */
1474 ftp_retrieve_glob (struct urlinfo *u, ccon *con, int action)
1476 struct fileinfo *orig, *start;
1479 con->cmd |= LEAVE_PENDING;
1481 orig = ftp_get_listing (u, con);
1483 /* First: weed out that do not conform the global rules given in
1484 opt.accepts and opt.rejects. */
1485 if (opt.accepts || opt.rejects)
1487 struct fileinfo *f = orig;
1491 if (f->type != FT_DIRECTORY && !acceptable (f->name))
1493 logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"), f->name);
1494 f = delelement (f, &start);
1500 /* Now weed out the files that do not match our globbing pattern.
1501 If we are dealing with a globbing pattern, that is. */
1502 if (*u->file && (action == GLOBALL || action == GETONE))
1505 struct fileinfo *f = start;
1509 matchres = fnmatch (u->file, f->name, 0);
1512 logprintf (LOG_NOTQUIET, "%s: %s\n", u->local,
1516 if (matchres == FNM_NOMATCH)
1517 f = delelement (f, &start); /* delete the element from the list */
1519 f = f->next; /* leave the element in the list */
1523 freefileinfo (start);
1524 return RETRBADPATTERN;
1530 /* Just get everything. */
1531 ftp_retrieve_list (u, start, con);
1535 if (action == GLOBALL)
1538 /* #### This message SUCKS. We should see what was the
1539 reason that nothing was retrieved. */
1540 logprintf (LOG_VERBOSE, _("No matches on pattern `%s'.\n"), u->file);
1542 else /* GETONE or GETALL */
1544 /* Let's try retrieving it anyway. */
1545 con->st |= ON_YOUR_OWN;
1546 res = ftp_loop_internal (u, NULL, con);
1550 freefileinfo (start);
1551 if (downloaded_exceeds_quota ())
1554 /* #### Should we return `res' here? */
1558 /* The wrapper that calls an appropriate routine according to contents
1559 of URL. Inherently, its capabilities are limited on what can be
1560 encoded into a URL. */
1562 ftp_loop (struct urlinfo *u, int *dt)
1564 ccon con; /* FTP connection */
1569 memset (&con, 0, sizeof (con));
1571 rbuf_uninitialize (&con.rbuf);
1572 con.st = ON_YOUR_OWN;
1575 res = RETROK; /* in case it's not used */
1577 /* If the file name is empty, the user probably wants a directory
1578 index. We'll provide one, properly HTML-ized. Unless
1579 opt.htmlify is 0, of course. :-) */
1580 if (!*u->file && !opt.recursive)
1582 struct fileinfo *f = ftp_get_listing (u, &con);
1588 char *filename = (opt.output_document
1589 ? xstrdup (opt.output_document)
1590 : (u->local ? xstrdup (u->local)
1591 : url_filename (u)));
1592 res = ftp_index (filename, u, f);
1593 if (res == FTPOK && opt.verbose)
1595 if (!opt.output_document)
1599 if (stat (filename, &st) == 0)
1603 logprintf (LOG_NOTQUIET,
1604 _("Wrote HTML-ized index to `%s' [%ld].\n"),
1608 logprintf (LOG_NOTQUIET,
1609 _("Wrote HTML-ized index to `%s'.\n"),
1619 int wild = has_wildcards_p (u->file);
1620 if ((opt.ftp_glob && wild) || opt.recursive || opt.timestamping)
1622 /* ftp_retrieve_glob is a catch-all function that gets called
1623 if we need globbing, time-stamping or recursion. Its
1624 third argument is just what we really need. */
1625 ftp_retrieve_glob (u, &con,
1626 (opt.ftp_glob && wild) ? GLOBALL : GETONE);
1629 res = ftp_loop_internal (u, NULL, &con);
1635 /* If a connection was left, quench it. */
1636 if (rbuf_initialized_p (&con.rbuf))
1637 CLOSE (RBUF_FD (&con.rbuf));
1638 FREE_MAYBE (con.id);
1643 /* Delete an element from the fileinfo linked list. Returns the
1644 address of the next element, or NULL if the list is exhausted. It
1645 can modify the start of the list. */
1646 static struct fileinfo *
1647 delelement (struct fileinfo *f, struct fileinfo **start)
1649 struct fileinfo *prev = f->prev;
1650 struct fileinfo *next = f->next;
1653 FREE_MAYBE (f->linkto);
1665 /* Free the fileinfo linked list of files. */
1667 freefileinfo (struct fileinfo *f)
1671 struct fileinfo *next = f->next;