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);
287 logputs (LOG_VERBOSE, "\n");
288 logputs (LOG_NOTQUIET, _("\
289 Error in server response, closing control connection.\n"));
291 rbuf_uninitialize (&con->rbuf);
295 /* Everything is OK. */
301 if (!opt.server_response)
302 logputs (LOG_VERBOSE, _("done.\n"));
304 /* Fifth: Set the FTP type. */
305 if (!opt.server_response)
306 logprintf (LOG_VERBOSE, "==> TYPE %c ... ", TOUPPER (u->ftp_type));
307 err = ftp_type (&con->rbuf, TOUPPER (u->ftp_type));
308 /* FTPRERR, WRITEFAILED, FTPUNKNOWNTYPE */
312 logputs (LOG_VERBOSE, "\n");
313 logputs (LOG_NOTQUIET, _("\
314 Error in server response, closing control connection.\n"));
316 rbuf_uninitialize (&con->rbuf);
320 logputs (LOG_VERBOSE, "\n");
321 logputs (LOG_NOTQUIET,
322 _("Write failed, closing control connection.\n"));
324 rbuf_uninitialize (&con->rbuf);
328 logputs (LOG_VERBOSE, "\n");
329 logprintf (LOG_NOTQUIET,
330 _("Unknown type `%c', closing control connection.\n"),
331 TOUPPER (u->ftp_type));
333 rbuf_uninitialize (&con->rbuf);
336 /* Everything is OK. */
342 if (!opt.server_response)
343 logputs (LOG_VERBOSE, _("done. "));
349 logputs (LOG_VERBOSE, _("==> CWD not needed.\n"));
352 /* Change working directory. If the FTP host runs VMS and
353 the path specified is absolute, we will have to convert
354 it to VMS style as VMS does not like leading slashes */
355 DEBUGP (("changing working directory\n"));
356 if (*(u->dir) == '/')
358 int pwd_len = strlen (con->id);
359 char *result = (char *)alloca (strlen (u->dir) + pwd_len + 10);
365 char *tmp_dir, *tmpp;
366 STRDUP_ALLOCA (tmp_dir, u->dir);
367 for (tmpp = tmp_dir; *tmpp; tmpp++)
370 strcpy (result, con->id);
371 /* pwd ends with ']', we have to get rid of it */
372 result[pwd_len - 1]= '\0';
373 strcat (result, tmp_dir);
374 strcat (result, "]");
380 /* pwd_len == 1 means pwd = "/", but u->dir begins with '/'
383 strcpy (result, con->id);
384 strcat (result, u->dir);
385 DEBUGP(("\npwd=\"%s\"", con->id));
386 DEBUGP(("\nu->dir=\"%s\"", u->dir));
392 if (!opt.server_response)
393 logprintf (LOG_VERBOSE, "==> CWD %s ... ", result);
394 err = ftp_cwd (&con->rbuf, result);
398 if (!opt.server_response)
399 logprintf (LOG_VERBOSE, "==> CWD %s ... ", u->dir);
400 err = ftp_cwd (&con->rbuf, u->dir);
402 /* FTPRERR, WRITEFAILED, FTPNSFOD */
406 logputs (LOG_VERBOSE, "\n");
407 logputs (LOG_NOTQUIET, _("\
408 Error in server response, closing control connection.\n"));
410 rbuf_uninitialize (&con->rbuf);
414 logputs (LOG_VERBOSE, "\n");
415 logputs (LOG_NOTQUIET,
416 _("Write failed, closing control connection.\n"));
418 rbuf_uninitialize (&con->rbuf);
422 logputs (LOG_VERBOSE, "\n");
423 logprintf (LOG_NOTQUIET, _("No such directory `%s'.\n\n"),
426 rbuf_uninitialize (&con->rbuf);
436 if (!opt.server_response)
437 logputs (LOG_VERBOSE, _("done.\n"));
440 else /* do not CWD */
441 logputs (LOG_VERBOSE, _("==> CWD not required.\n"));
443 /* If anything is to be retrieved, PORT (or PASV) must be sent. */
444 if (cmd & (DO_LIST | DO_RETR))
446 if (opt.ftp_pasv > 0)
449 unsigned short tport;
451 if (!opt.server_response)
452 logputs (LOG_VERBOSE, "==> PASV ... ");
453 err = ftp_pasv (&con->rbuf, pasv_addr);
454 /* FTPRERR, WRITEFAILED, FTPNOPASV, FTPINVPASV */
458 logputs (LOG_VERBOSE, "\n");
459 logputs (LOG_NOTQUIET, _("\
460 Error in server response, closing control connection.\n"));
462 rbuf_uninitialize (&con->rbuf);
466 logputs (LOG_VERBOSE, "\n");
467 logputs (LOG_NOTQUIET,
468 _("Write failed, closing control connection.\n"));
470 rbuf_uninitialize (&con->rbuf);
474 logputs (LOG_VERBOSE, "\n");
475 logputs (LOG_NOTQUIET, _("Cannot initiate PASV transfer.\n"));
478 logputs (LOG_VERBOSE, "\n");
479 logputs (LOG_NOTQUIET, _("Cannot parse PASV response.\n"));
490 sprintf (thost, "%d.%d.%d.%d",
491 pasv_addr[0], pasv_addr[1], pasv_addr[2], pasv_addr[3]);
492 tport = (pasv_addr[4] << 8) + pasv_addr[5];
493 DEBUGP ((_("Will try connecting to %s:%hu.\n"), thost, tport));
494 err = make_connection (&dtsock, thost, tport);
497 /* Do not close the socket in first several cases,
498 since it wasn't created at all. */
500 logputs (LOG_VERBOSE, "\n");
501 logprintf (LOG_NOTQUIET, "%s: %s\n", thost,
504 rbuf_uninitialize (&con->rbuf);
508 logputs (LOG_VERBOSE, "\n");
509 logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
511 rbuf_uninitialize (&con->rbuf);
515 logputs (LOG_VERBOSE, "\n");
516 logprintf (LOG_NOTQUIET,
517 _("Connection to %s:%hu refused.\n"),
520 rbuf_uninitialize (&con->rbuf);
524 logputs (LOG_VERBOSE, "\n");
525 logprintf (LOG_NOTQUIET, "connect: %s\n",
528 rbuf_uninitialize (&con->rbuf);
536 passive_mode_open= 1; /* Flag to avoid accept port */
537 if (!opt.server_response)
538 logputs (LOG_VERBOSE, _("done. "));
542 if (!passive_mode_open) /* Try to use a port command if PASV failed */
544 if (!opt.server_response)
545 logputs (LOG_VERBOSE, "==> PORT ... ");
546 err = ftp_port (&con->rbuf);
547 /* FTPRERR, WRITEFAILED, bindport (CONSOCKERR, CONPORTERR, BINDERR,
548 LISTENERR), HOSTERR, FTPPORTERR */
552 logputs (LOG_VERBOSE, "\n");
553 logputs (LOG_NOTQUIET, _("\
554 Error in server response, closing control connection.\n"));
557 rbuf_uninitialize (&con->rbuf);
561 logputs (LOG_VERBOSE, "\n");
562 logputs (LOG_NOTQUIET,
563 _("Write failed, closing control connection.\n"));
566 rbuf_uninitialize (&con->rbuf);
570 logputs (LOG_VERBOSE, "\n");
571 logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
574 rbuf_uninitialize (&con->rbuf);
577 case CONPORTERR: case BINDERR: case LISTENERR:
578 /* What now? These problems are local... */
579 logputs (LOG_VERBOSE, "\n");
580 logprintf (LOG_NOTQUIET, _("Bind error (%s).\n"),
586 logputs (LOG_VERBOSE, "\n");
587 logprintf (LOG_NOTQUIET, "%s: %s\n", u->host,
591 rbuf_uninitialize (&con->rbuf);
595 logputs (LOG_VERBOSE, "\n");
596 logputs (LOG_NOTQUIET, _("Invalid PORT.\n"));
599 rbuf_uninitialize (&con->rbuf);
609 if (!opt.server_response)
610 logputs (LOG_VERBOSE, _("done. "));
612 } /* cmd & (DO_LIST | DO_RETR) */
614 /* Restart if needed. */
615 if (restval && (cmd & DO_RETR))
617 if (!opt.server_response)
618 logprintf (LOG_VERBOSE, "==> REST %ld ... ", restval);
619 err = ftp_rest (&con->rbuf, restval);
621 /* FTPRERR, WRITEFAILED, FTPRESTFAIL */
625 logputs (LOG_VERBOSE, "\n");
626 logputs (LOG_NOTQUIET, _("\
627 Error in server response, closing control connection.\n"));
630 rbuf_uninitialize (&con->rbuf);
634 logputs (LOG_VERBOSE, "\n");
635 logputs (LOG_NOTQUIET,
636 _("Write failed, closing control connection.\n"));
639 rbuf_uninitialize (&con->rbuf);
643 /* If `-c' is specified and the file already existed when
644 Wget was started, it would be a bad idea for us to start
645 downloading it from scratch, effectively truncating it. */
646 if (opt.always_rest && (cmd & NO_TRUNCATE))
648 logprintf (LOG_NOTQUIET,
649 _("\nREST failed; will not truncate `%s'.\n"),
653 rbuf_uninitialize (&con->rbuf);
654 return CONTNOTSUPPORTED;
656 logputs (LOG_VERBOSE, _("\nREST failed, starting from scratch.\n"));
666 if (err != FTPRESTFAIL && !opt.server_response)
667 logputs (LOG_VERBOSE, _("done. "));
668 } /* restval && cmd & DO_RETR */
674 if (!opt.server_response)
677 logputs (LOG_VERBOSE, "\n");
678 logprintf (LOG_VERBOSE, "==> RETR %s ... ", u->file);
681 err = ftp_retr (&con->rbuf, u->file);
682 /* FTPRERR, WRITEFAILED, FTPNSFOD */
686 logputs (LOG_VERBOSE, "\n");
687 logputs (LOG_NOTQUIET, _("\
688 Error in server response, closing control connection.\n"));
691 rbuf_uninitialize (&con->rbuf);
695 logputs (LOG_VERBOSE, "\n");
696 logputs (LOG_NOTQUIET,
697 _("Write failed, closing control connection.\n"));
700 rbuf_uninitialize (&con->rbuf);
704 logputs (LOG_VERBOSE, "\n");
705 logprintf (LOG_NOTQUIET, _("No such file `%s'.\n\n"), u->file);
717 if (!opt.server_response)
718 logputs (LOG_VERBOSE, _("done.\n"));
719 expected_bytes = ftp_expected_bytes (ftp_last_respline);
724 if (!opt.server_response)
725 logputs (LOG_VERBOSE, "==> LIST ... ");
726 /* As Maciej W. Rozycki (macro@ds2.pg.gda.pl) says, `LIST'
727 without arguments is better than `LIST .'; confirmed by
729 err = ftp_list (&con->rbuf, NULL);
730 /* FTPRERR, WRITEFAILED */
734 logputs (LOG_VERBOSE, "\n");
735 logputs (LOG_NOTQUIET, _("\
736 Error in server response, closing control connection.\n"));
739 rbuf_uninitialize (&con->rbuf);
743 logputs (LOG_VERBOSE, "\n");
744 logputs (LOG_NOTQUIET,
745 _("Write failed, closing control connection.\n"));
748 rbuf_uninitialize (&con->rbuf);
752 logputs (LOG_VERBOSE, "\n");
753 logprintf (LOG_NOTQUIET, _("No such file or directory `%s'.\n\n"),
765 if (!opt.server_response)
766 logputs (LOG_VERBOSE, _("done.\n"));
767 expected_bytes = ftp_expected_bytes (ftp_last_respline);
768 } /* cmd & DO_LIST */
770 /* Some FTP servers return the total length of file after REST
771 command, others just return the remaining size. */
772 if (*len && restval && expected_bytes
773 && (expected_bytes == *len - restval))
775 DEBUGP (("Lying FTP server found, adjusting.\n"));
776 expected_bytes = *len;
779 /* If no transmission was required, then everything is OK. */
780 if (!(cmd & (DO_LIST | DO_RETR)))
783 if (!passive_mode_open) /* we are not using pasive mode so we need
786 /* Open the data transmission socket by calling acceptport(). */
787 err = acceptport (&dtsock);
788 /* Possible errors: ACCEPTERR. */
789 if (err == ACCEPTERR)
791 logprintf (LOG_NOTQUIET, "accept: %s\n", strerror (errno));
796 /* Open the file -- if opt.dfp is set, use it instead. */
797 if (!opt.dfp || con->cmd & DO_LIST)
799 mkalldirs (u->local);
801 rotate_backups (u->local);
802 /* #### Is this correct? */
803 chmod (u->local, 0600);
805 fp = fopen (u->local, restval ? "ab" : "wb");
808 logprintf (LOG_NOTQUIET, "%s: %s\n", u->local, strerror (errno));
810 rbuf_uninitialize (&con->rbuf);
817 extern int global_download_count;
820 /* Rewind the output document if the download starts over and if
821 this is the first download. See gethttp() for a longer
823 if (!restval && global_download_count == 0)
825 /* This will silently fail for streams that don't correspond
826 to regular files, but that's OK. */
828 /* ftruncate is needed because opt.dfp is opened in append
829 mode if opt.always_rest is set. */
830 ftruncate (fileno (fp), 0);
837 logprintf (LOG_VERBOSE, _("Length: %s"), legible (*len));
839 logprintf (LOG_VERBOSE, _(" [%s to go]"), legible (*len - restval));
840 logputs (LOG_VERBOSE, "\n");
842 else if (expected_bytes)
844 logprintf (LOG_VERBOSE, _("Length: %s"), legible (expected_bytes));
846 logprintf (LOG_VERBOSE, _(" [%s to go]"),
847 legible (expected_bytes - restval));
848 logputs (LOG_VERBOSE, _(" (unauthoritative)\n"));
851 /* Get the contents of the document. */
852 res = get_contents (dtsock, fp, len, restval, expected_bytes, &con->rbuf, 0);
853 con->dltime = elapsed_time ();
854 tms = time_str (NULL);
855 tmrate = rate (*len - restval, con->dltime, 0);
856 /* Close data connection socket. */
858 /* Close the local file. */
860 /* Close or flush the file. We have to be careful to check for
861 error here. Checking the result of fwrite() is not enough --
862 errors could go unnoticed! */
864 if (!opt.dfp || con->cmd & DO_LIST)
865 flush_res = fclose (fp);
867 flush_res = fflush (fp);
868 if (flush_res == EOF)
871 /* If get_contents couldn't write to fp, bail out. */
874 logprintf (LOG_NOTQUIET, _("%s: %s, closing control connection.\n"),
875 u->local, strerror (errno));
877 rbuf_uninitialize (&con->rbuf);
882 logprintf (LOG_NOTQUIET, _("%s (%s) - Data connection: %s; "),
883 tms, tmrate, strerror (errno));
884 if (opt.server_response)
885 logputs (LOG_ALWAYS, "\n");
888 /* Get the server to tell us if everything is retrieved. */
889 err = ftp_response (&con->rbuf, &respline);
890 /* ...and empty the buffer. */
891 rbuf_discard (&con->rbuf);
895 /* The control connection is decidedly closed. Print the time
896 only if it hasn't already been printed. */
898 logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
899 logputs (LOG_NOTQUIET, _("Control connection closed.\n"));
900 /* If there is an error on the control connection, close it, but
901 return FTPRETRINT, since there is a possibility that the
902 whole file was retrieved nevertheless (but that is for
903 ftp_loop_internal to decide). */
905 rbuf_uninitialize (&con->rbuf);
908 /* If retrieval failed for any reason, return FTPRETRINT, but do not
909 close socket, since the control connection is still alive. If
910 there is something wrong with the control connection, it will
911 become apparent later. */
912 if (*respline != '2')
916 logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
917 logputs (LOG_NOTQUIET, _("Data transfer aborted.\n"));
924 /* What now? The data connection was erroneous, whereas the
925 response says everything is OK. We shall play it safe. */
929 if (!(cmd & LEAVE_PENDING))
931 /* I should probably send 'QUIT' and check for a reply, but this
932 is faster. #### Is it OK, though? */
934 rbuf_uninitialize (&con->rbuf);
936 /* If it was a listing, and opt.server_response is true,
938 if (opt.server_response && (con->cmd & DO_LIST))
940 mkalldirs (u->local);
941 fp = fopen (u->local, "r");
943 logprintf (LOG_ALWAYS, "%s: %s\n", u->local, strerror (errno));
947 /* The lines are being read with read_whole_line because of
948 no-buffering on opt.lfile. */
949 while ((line = read_whole_line (fp)))
951 logprintf (LOG_ALWAYS, "%s\n", line);
956 } /* con->cmd & DO_LIST && server_response */
961 /* A one-file FTP loop. This is the part where FTP retrieval is
962 retried, and retried, and retried, and...
964 This loop either gets commands from con, or (if ON_YOUR_OWN is
965 set), makes them up to retrieve the file given by the URL. */
967 ftp_loop_internal (struct urlinfo *u, struct fileinfo *f, ccon *con)
969 int count, orig_lp, no_truncate;
971 char *tms, *tmrate, *locf;
976 u->local = url_filename (u);
978 if (opt.noclobber && file_exists_p (u->local))
980 logprintf (LOG_VERBOSE,
981 _("File `%s' already there, not retrieving.\n"), u->local);
982 /* If the file is there, we suppose it's retrieved OK. */
986 /* Remove it if it's a link. */
987 remove_link (u->local);
988 if (!opt.output_document)
991 locf = opt.output_document;
995 if (con->st & ON_YOUR_OWN)
996 con->st = ON_YOUR_OWN;
998 orig_lp = con->cmd & LEAVE_PENDING ? 1 : 0;
1000 /* In `-c' is used, check whether the file we're writing to exists
1001 before we've done anything. If so, we'll refuse to truncate it
1002 if the server doesn't support continued downloads. */
1004 if (opt.always_rest)
1005 no_truncate = file_exists_p (locf);
1010 /* Increment the pass counter. */
1012 sleep_between_retrievals (count);
1013 if (con->st & ON_YOUR_OWN)
1016 con->cmd |= (DO_RETR | LEAVE_PENDING);
1017 if (rbuf_initialized_p (&con->rbuf))
1018 con->cmd &= ~ (DO_LOGIN | DO_CWD);
1020 con->cmd |= (DO_LOGIN | DO_CWD);
1022 else /* not on your own */
1024 if (rbuf_initialized_p (&con->rbuf))
1025 con->cmd &= ~DO_LOGIN;
1027 con->cmd |= DO_LOGIN;
1028 if (con->st & DONE_CWD)
1029 con->cmd &= ~DO_CWD;
1034 con->cmd |= NO_TRUNCATE;
1035 /* Assume no restarting. */
1037 if ((count > 1 || opt.always_rest)
1038 && !(con->cmd & DO_LIST)
1039 && file_exists_p (locf))
1040 if (stat (locf, &st) == 0 && S_ISREG (st.st_mode))
1041 restval = st.st_size;
1042 /* Get the current time string. */
1043 tms = time_str (NULL);
1044 /* Print fetch message, if opt.verbose. */
1047 char *hurl = str_url (u->proxy ? u->proxy : u, 1);
1051 sprintf (tmp, _("(try:%2d)"), count);
1052 logprintf (LOG_VERBOSE, "--%s-- %s\n %s => `%s'\n",
1053 tms, hurl, tmp, locf);
1055 ws_changetitle (hurl, 1);
1059 /* Send getftp the proper length, if fileinfo was provided. */
1064 err = getftp (u, &len, restval, con);
1066 tms = time_str (NULL);
1067 tmrate = rate (len - restval, con->dltime, 0);
1069 if (!rbuf_initialized_p (&con->rbuf))
1070 con->st &= ~DONE_CWD;
1072 con->st |= DONE_CWD;
1076 case HOSTERR: case CONREFUSED: case FWRITEERR: case FOPENERR:
1077 case FTPNSFOD: case FTPLOGINC: case FTPNOPASV: case CONTNOTSUPPORTED:
1078 /* Fatal errors, give up. */
1081 case CONSOCKERR: case CONERROR: case FTPSRVERR: case FTPRERR:
1082 case WRITEFAILED: case FTPUNKNOWNTYPE: case CONPORTERR:
1083 case BINDERR: case LISTENERR: case ACCEPTERR:
1084 case FTPPORTERR: case FTPLOGREFUSED: case FTPINVPASV:
1085 printwhat (count, opt.ntry);
1086 /* non-fatal errors */
1090 /* If the control connection was closed, the retrieval
1091 will be considered OK if f->size == len. */
1092 if (!f || len != f->size)
1094 printwhat (count, opt.ntry);
1106 /* If we get out of the switch above without continue'ing, we've
1107 successfully downloaded a file. Remember this fact. */
1108 downloaded_file(FILE_DOWNLOADED_NORMALLY, locf);
1110 if (con->st & ON_YOUR_OWN)
1112 CLOSE (RBUF_FD (&con->rbuf));
1113 rbuf_uninitialize (&con->rbuf);
1115 logprintf (LOG_VERBOSE, _("%s (%s) - `%s' saved [%ld]\n\n"),
1116 tms, tmrate, locf, len);
1117 if (!opt.verbose && !opt.quiet)
1119 /* Need to hide the password from the URL. The `if' is here
1120 so that we don't do the needless allocation every
1122 char *hurl = str_url (u->proxy ? u->proxy : u, 1);
1123 logprintf (LOG_NONVERBOSE, "%s URL: %s [%ld] -> \"%s\" [%d]\n",
1124 tms, hurl, len, locf, count);
1128 if ((con->cmd & DO_LIST))
1129 /* This is a directory listing file. */
1131 if (!opt.remove_listing)
1132 /* --dont-remove-listing was specified, so do count this towards the
1133 number of bytes and files downloaded. */
1135 downloaded_increase (len);
1139 /* Deletion of listing files is not controlled by --delete-after, but
1140 by the more specific option --dont-remove-listing, and the code
1141 to do this deletion is in another function. */
1144 /* This is not a directory listing file. */
1146 /* Unlike directory listing files, don't pretend normal files weren't
1147 downloaded if they're going to be deleted. People seeding proxies,
1148 for instance, may want to know how many bytes and files they've
1149 downloaded through it. */
1150 downloaded_increase (len);
1153 if (opt.delete_after)
1155 DEBUGP (("Removing file due to --delete-after in"
1156 " ftp_loop_internal():\n"));
1157 logprintf (LOG_VERBOSE, _("Removing %s.\n"), locf);
1159 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1163 /* Restore the original leave-pendingness. */
1165 con->cmd |= LEAVE_PENDING;
1167 con->cmd &= ~LEAVE_PENDING;
1169 } while (!opt.ntry || (count < opt.ntry));
1171 if (rbuf_initialized_p (&con->rbuf) && (con->st & ON_YOUR_OWN))
1173 CLOSE (RBUF_FD (&con->rbuf));
1174 rbuf_uninitialize (&con->rbuf);
1179 /* Return the directory listing in a reusable format. The directory
1180 is specifed in u->dir. */
1182 ftp_get_listing (struct urlinfo *u, ccon *con, struct fileinfo **f)
1185 char *olocal = u->local;
1186 char *list_filename, *ofile;
1188 con->st &= ~ON_YOUR_OWN;
1189 con->cmd |= (DO_LIST | LEAVE_PENDING);
1190 con->cmd &= ~DO_RETR;
1191 /* Get the listing filename. */
1193 u->file = LIST_FILENAME;
1194 list_filename = url_filename (u);
1196 u->local = list_filename;
1197 DEBUGP ((_("Using `%s' as listing tmp file.\n"), list_filename));
1198 err = ftp_loop_internal (u, NULL, con);
1201 *f = ftp_parse_ls (list_filename, con->rs);
1204 if (opt.remove_listing)
1206 if (unlink (list_filename))
1207 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1209 logprintf (LOG_VERBOSE, _("Removed `%s'.\n"), list_filename);
1211 xfree (list_filename);
1212 con->cmd &= ~DO_LIST;
1216 static uerr_t ftp_retrieve_dirs PARAMS ((struct urlinfo *, struct fileinfo *,
1218 static uerr_t ftp_retrieve_glob PARAMS ((struct urlinfo *, ccon *, int));
1219 static struct fileinfo *delelement PARAMS ((struct fileinfo *,
1220 struct fileinfo **));
1221 static void freefileinfo PARAMS ((struct fileinfo *f));
1223 /* Retrieve a list of files given in struct fileinfo linked list. If
1224 a file is a symbolic link, do not retrieve it, but rather try to
1225 set up a similar link on the local disk, if the symlinks are
1228 If opt.recursive is set, after all files have been retrieved,
1229 ftp_retrieve_dirs will be called to retrieve the directories. */
1231 ftp_retrieve_list (struct urlinfo *u, struct fileinfo *f, ccon *con)
1233 static int depth = 0;
1235 char *olocal, *ofile;
1236 struct fileinfo *orig;
1241 /* Increase the depth. */
1243 if (opt.reclevel != INFINITE_RECURSION && depth > opt.reclevel)
1245 DEBUGP ((_("Recursion depth %d exceeded max. depth %d.\n"),
1246 depth, opt.reclevel));
1254 con->st &= ~ON_YOUR_OWN;
1255 if (!(con->st & DONE_CWD))
1258 con->cmd &= ~DO_CWD;
1259 con->cmd |= (DO_RETR | LEAVE_PENDING);
1261 if (!rbuf_initialized_p (&con->rbuf))
1262 con->cmd |= DO_LOGIN;
1264 con->cmd &= ~DO_LOGIN;
1266 err = RETROK; /* in case it's not used */
1270 if (downloaded_exceeds_quota ())
1278 u->local = url_filename (u);
1282 if (opt.timestamping && f->type == FT_PLAINFILE)
1285 /* If conversion of HTML files retrieved via FTP is ever implemented,
1286 we'll need to stat() <file>.orig here when -K has been specified.
1287 I'm not implementing it now since files on an FTP server are much
1288 more likely than files on an HTTP server to legitimately have a
1290 if (!stat (u->local, &st))
1294 /* Else, get it from the file. */
1295 local_size = st.st_size;
1297 /* Compare file sizes only for servers that tell us correct
1298 values. Assumme sizes being equal for servers that lie
1300 cor_val = (con->rs == ST_UNIX || con->rs == ST_WINNT);
1301 eq_size = cor_val ? (local_size == f->size) : 1 ;
1302 if (f->tstamp <= tml && eq_size)
1304 /* Remote file is older, file sizes can be compared and
1306 logprintf (LOG_VERBOSE, _("\
1307 Remote file no newer than local file `%s' -- not retrieving.\n"), u->local);
1312 /* Remote file is newer or sizes cannot be matched */
1313 logprintf (LOG_VERBOSE, _("\
1314 Remote file is newer than local file `%s' -- retrieving.\n\n"),
1319 /* Sizes do not match */
1320 logprintf (LOG_VERBOSE, _("\
1321 The sizes do not match (local %ld) -- retrieving.\n\n"), local_size);
1324 } /* opt.timestamping && f->type == FT_PLAINFILE */
1328 /* If opt.retr_symlinks is defined, we treat symlinks as
1329 if they were normal files. There is currently no way
1330 to distinguish whether they might be directories, and
1332 if (!opt.retr_symlinks)
1336 logputs (LOG_NOTQUIET,
1337 _("Invalid name of the symlink, skipping.\n"));
1341 /* Check whether we already have the correct
1343 int rc = lstat (u->local, &st);
1346 size_t len = strlen (f->linkto) + 1;
1347 if (S_ISLNK (st.st_mode))
1349 char *link_target = (char *)alloca (len);
1350 size_t n = readlink (u->local, link_target, len);
1352 && (memcmp (link_target, f->linkto, n) == 0))
1354 logprintf (LOG_VERBOSE, _("\
1355 Already have correct symlink %s -> %s\n\n"),
1356 u->local, f->linkto);
1362 logprintf (LOG_VERBOSE, _("Creating symlink %s -> %s\n"),
1363 u->local, f->linkto);
1364 /* Unlink before creating symlink! */
1366 if (symlink (f->linkto, u->local) == -1)
1367 logprintf (LOG_NOTQUIET, "symlink: %s\n",
1369 logputs (LOG_VERBOSE, "\n");
1370 } /* have f->linkto */
1371 #else /* not HAVE_SYMLINK */
1372 logprintf (LOG_NOTQUIET,
1373 _("Symlinks not supported, skipping symlink `%s'.\n"),
1375 #endif /* not HAVE_SYMLINK */
1377 else /* opt.retr_symlinks */
1380 err = ftp_loop_internal (u, f, con);
1381 } /* opt.retr_symlinks */
1385 logprintf (LOG_NOTQUIET, _("Skipping directory `%s'.\n"),
1389 /* Call the retrieve loop. */
1391 err = ftp_loop_internal (u, f, con);
1394 logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
1399 /* Set the time-stamp information to the local file. Symlinks
1400 are not to be stamped because it sets the stamp on the
1402 if (!(f->type == FT_SYMLINK && !opt.retr_symlinks)
1405 && file_exists_p (u->local))
1407 /* #### This code repeats in http.c and ftp.c. Move it to a
1409 const char *fl = NULL;
1410 if (opt.output_document)
1412 if (opt.od_known_regular)
1413 fl = opt.output_document;
1418 touch (fl, f->tstamp);
1420 else if (f->tstamp == -1)
1421 logprintf (LOG_NOTQUIET, _("%s: corrupt time-stamp.\n"), u->local);
1423 if (f->perms && f->type == FT_PLAINFILE && dlthis)
1424 chmod (u->local, f->perms);
1426 DEBUGP (("Unrecognized permissions for %s.\n", u->local));
1431 /* Break on fatals. */
1432 if (err == QUOTEXC || err == HOSTERR || err == FWRITEERR)
1434 con->cmd &= ~ (DO_CWD | DO_LOGIN);
1437 /* We do not want to call ftp_retrieve_dirs here */
1438 if (opt.recursive &&
1439 !(opt.reclevel != INFINITE_RECURSION && depth >= opt.reclevel))
1440 err = ftp_retrieve_dirs (u, orig, con);
1441 else if (opt.recursive)
1442 DEBUGP ((_("Will not retrieve dirs since depth is %d (max %d).\n"),
1443 depth, opt.reclevel));
1448 /* Retrieve the directories given in a file list. This function works
1449 by simply going through the linked list and calling
1450 ftp_retrieve_glob on each directory entry. The function knows
1451 about excluded directories. */
1453 ftp_retrieve_dirs (struct urlinfo *u, struct fileinfo *f, ccon *con)
1456 char *current_container = NULL;
1457 int current_length = 0;
1459 for (; f; f = f->next)
1463 if (downloaded_exceeds_quota ())
1465 if (f->type != FT_DIRECTORY)
1468 len = 1 + strlen (u->dir) + 1 + strlen (f->name) + 1;
1469 /* Allocate u->dir off stack, but reallocate only if a larger
1470 string is needed. */
1471 if (len > current_length)
1472 current_container = (char *)alloca (len);
1473 u->dir = current_container;
1474 sprintf (u->dir, "/%s%s%s", odir + (*odir == '/'),
1475 (!*odir || (*odir == '/' && !* (odir + 1))) ? "" : "/", f->name);
1476 if (!accdir (u->dir, ALLABS))
1478 logprintf (LOG_VERBOSE, _("\
1479 Not descending to `%s' as it is excluded/not-included.\n"), u->dir);
1483 con->st &= ~DONE_CWD;
1484 ftp_retrieve_glob (u, con, GETALL);
1485 /* Set the time-stamp? */
1488 if (opt.quota && opt.downloaded > opt.quota)
1495 /* A near-top-level function to retrieve the files in a directory.
1496 The function calls ftp_get_listing, to get a linked list of files.
1497 Then it weeds out the file names that do not match the pattern.
1498 ftp_retrieve_list is called with this updated list as an argument.
1500 If the argument ACTION is GETONE, just download the file (but first
1501 get the listing, so that the time-stamp is heeded); if it's GLOBALL,
1502 use globbing; if it's GETALL, download the whole directory. */
1504 ftp_retrieve_glob (struct urlinfo *u, ccon *con, int action)
1506 struct fileinfo *orig, *start;
1509 con->cmd |= LEAVE_PENDING;
1511 res = ftp_get_listing (u, con, &orig);
1515 /* First: weed out that do not conform the global rules given in
1516 opt.accepts and opt.rejects. */
1517 if (opt.accepts || opt.rejects)
1519 struct fileinfo *f = orig;
1523 if (f->type != FT_DIRECTORY && !acceptable (f->name))
1525 logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"), f->name);
1526 f = delelement (f, &start);
1532 /* Now weed out the files that do not match our globbing pattern.
1533 If we are dealing with a globbing pattern, that is. */
1534 if (*u->file && (action == GLOBALL || action == GETONE))
1537 struct fileinfo *f = start;
1541 matchres = fnmatch (u->file, f->name, 0);
1544 logprintf (LOG_NOTQUIET, "%s: %s\n", u->local,
1548 if (matchres == FNM_NOMATCH)
1549 f = delelement (f, &start); /* delete the element from the list */
1551 f = f->next; /* leave the element in the list */
1555 freefileinfo (start);
1556 return RETRBADPATTERN;
1562 /* Just get everything. */
1563 ftp_retrieve_list (u, start, con);
1567 if (action == GLOBALL)
1570 /* #### This message SUCKS. We should see what was the
1571 reason that nothing was retrieved. */
1572 logprintf (LOG_VERBOSE, _("No matches on pattern `%s'.\n"), u->file);
1574 else /* GETONE or GETALL */
1576 /* Let's try retrieving it anyway. */
1577 con->st |= ON_YOUR_OWN;
1578 res = ftp_loop_internal (u, NULL, con);
1582 freefileinfo (start);
1583 if (downloaded_exceeds_quota ())
1586 /* #### Should we return `res' here? */
1590 /* The wrapper that calls an appropriate routine according to contents
1591 of URL. Inherently, its capabilities are limited on what can be
1592 encoded into a URL. */
1594 ftp_loop (struct urlinfo *u, int *dt)
1596 ccon con; /* FTP connection */
1601 memset (&con, 0, sizeof (con));
1603 rbuf_uninitialize (&con.rbuf);
1604 con.st = ON_YOUR_OWN;
1607 res = RETROK; /* in case it's not used */
1609 /* If the file name is empty, the user probably wants a directory
1610 index. We'll provide one, properly HTML-ized. Unless
1611 opt.htmlify is 0, of course. :-) */
1612 if (!*u->file && !opt.recursive)
1615 res = ftp_get_listing (u, &con, &f);
1621 char *filename = (opt.output_document
1622 ? xstrdup (opt.output_document)
1623 : (u->local ? xstrdup (u->local)
1624 : url_filename (u)));
1625 res = ftp_index (filename, u, f);
1626 if (res == FTPOK && opt.verbose)
1628 if (!opt.output_document)
1632 if (stat (filename, &st) == 0)
1636 logprintf (LOG_NOTQUIET,
1637 _("Wrote HTML-ized index to `%s' [%ld].\n"),
1641 logprintf (LOG_NOTQUIET,
1642 _("Wrote HTML-ized index to `%s'.\n"),
1652 int wild = has_wildcards_p (u->file);
1653 if ((opt.ftp_glob && wild) || opt.recursive || opt.timestamping)
1655 /* ftp_retrieve_glob is a catch-all function that gets called
1656 if we need globbing, time-stamping or recursion. Its
1657 third argument is just what we really need. */
1658 ftp_retrieve_glob (u, &con,
1659 (opt.ftp_glob && wild) ? GLOBALL : GETONE);
1662 res = ftp_loop_internal (u, NULL, &con);
1668 /* If a connection was left, quench it. */
1669 if (rbuf_initialized_p (&con.rbuf))
1670 CLOSE (RBUF_FD (&con.rbuf));
1671 FREE_MAYBE (con.id);
1676 /* Delete an element from the fileinfo linked list. Returns the
1677 address of the next element, or NULL if the list is exhausted. It
1678 can modify the start of the list. */
1679 static struct fileinfo *
1680 delelement (struct fileinfo *f, struct fileinfo **start)
1682 struct fileinfo *prev = f->prev;
1683 struct fileinfo *next = f->next;
1686 FREE_MAYBE (f->linkto);
1698 /* Free the fileinfo linked list of files. */
1700 freefileinfo (struct fileinfo *f)
1704 struct fileinfo *next = f->next;