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 char *target = u->dir;
354 DEBUGP (("changing working directory\n"));
356 /* Change working directory. To change to a non-absolute
357 Unix directory, we need to prepend initial directory
358 (con->id) to it. Absolute directories "just work". */
362 int idlen = strlen (con->id);
363 char *ntarget = (char *)alloca (idlen + 1 + strlen (u->dir) + 1);
364 /* pwd_len == 1 means pwd = "/" */
365 sprintf (ntarget, "%s%s%s", con->id, idlen == 1 ? "" : "/",
370 /* If the FTP host runs VMS, we will have to convert it to
371 VMS style as VMS does not like leading slashes. "VMS
372 style" is [dir.subdir.subsubdir]. */
373 if (con->rs == ST_VMS)
376 char *ntarget = (char *)alloca (strlen (target) + 1);
377 strcpy (ntarget, target);
378 assert (*ntarget == '/');
380 for (tmpp = ntarget + 1; *tmpp; tmpp++)
388 if (!opt.server_response)
389 logprintf (LOG_VERBOSE, "==> CWD %s ... ", target);
390 err = ftp_cwd (&con->rbuf, target);
391 /* FTPRERR, WRITEFAILED, FTPNSFOD */
395 logputs (LOG_VERBOSE, "\n");
396 logputs (LOG_NOTQUIET, _("\
397 Error in server response, closing control connection.\n"));
399 rbuf_uninitialize (&con->rbuf);
403 logputs (LOG_VERBOSE, "\n");
404 logputs (LOG_NOTQUIET,
405 _("Write failed, closing control connection.\n"));
407 rbuf_uninitialize (&con->rbuf);
411 logputs (LOG_VERBOSE, "\n");
412 logprintf (LOG_NOTQUIET, _("No such directory `%s'.\n\n"),
415 rbuf_uninitialize (&con->rbuf);
425 if (!opt.server_response)
426 logputs (LOG_VERBOSE, _("done.\n"));
429 else /* do not CWD */
430 logputs (LOG_VERBOSE, _("==> CWD not required.\n"));
432 /* If anything is to be retrieved, PORT (or PASV) must be sent. */
433 if (cmd & (DO_LIST | DO_RETR))
435 if (opt.ftp_pasv > 0)
438 unsigned short tport;
440 if (!opt.server_response)
441 logputs (LOG_VERBOSE, "==> PASV ... ");
442 err = ftp_pasv (&con->rbuf, pasv_addr);
443 /* FTPRERR, WRITEFAILED, FTPNOPASV, FTPINVPASV */
447 logputs (LOG_VERBOSE, "\n");
448 logputs (LOG_NOTQUIET, _("\
449 Error in server response, closing control connection.\n"));
451 rbuf_uninitialize (&con->rbuf);
455 logputs (LOG_VERBOSE, "\n");
456 logputs (LOG_NOTQUIET,
457 _("Write failed, closing control connection.\n"));
459 rbuf_uninitialize (&con->rbuf);
463 logputs (LOG_VERBOSE, "\n");
464 logputs (LOG_NOTQUIET, _("Cannot initiate PASV transfer.\n"));
467 logputs (LOG_VERBOSE, "\n");
468 logputs (LOG_NOTQUIET, _("Cannot parse PASV response.\n"));
479 sprintf (thost, "%d.%d.%d.%d",
480 pasv_addr[0], pasv_addr[1], pasv_addr[2], pasv_addr[3]);
481 tport = (pasv_addr[4] << 8) + pasv_addr[5];
482 DEBUGP ((_("Will try connecting to %s:%hu.\n"), thost, tport));
483 err = make_connection (&dtsock, thost, tport);
486 /* Do not close the socket in first several cases,
487 since it wasn't created at all. */
489 logputs (LOG_VERBOSE, "\n");
490 logprintf (LOG_NOTQUIET, "%s: %s\n", thost,
493 rbuf_uninitialize (&con->rbuf);
497 logputs (LOG_VERBOSE, "\n");
498 logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
500 rbuf_uninitialize (&con->rbuf);
504 logputs (LOG_VERBOSE, "\n");
505 logprintf (LOG_NOTQUIET,
506 _("Connection to %s:%hu refused.\n"),
509 rbuf_uninitialize (&con->rbuf);
513 logputs (LOG_VERBOSE, "\n");
514 logprintf (LOG_NOTQUIET, "connect: %s\n",
517 rbuf_uninitialize (&con->rbuf);
525 passive_mode_open= 1; /* Flag to avoid accept port */
526 if (!opt.server_response)
527 logputs (LOG_VERBOSE, _("done. "));
531 if (!passive_mode_open) /* Try to use a port command if PASV failed */
533 if (!opt.server_response)
534 logputs (LOG_VERBOSE, "==> PORT ... ");
535 err = ftp_port (&con->rbuf);
536 /* FTPRERR, WRITEFAILED, bindport (CONSOCKERR, CONPORTERR, BINDERR,
537 LISTENERR), HOSTERR, FTPPORTERR */
541 logputs (LOG_VERBOSE, "\n");
542 logputs (LOG_NOTQUIET, _("\
543 Error in server response, closing control connection.\n"));
546 rbuf_uninitialize (&con->rbuf);
550 logputs (LOG_VERBOSE, "\n");
551 logputs (LOG_NOTQUIET,
552 _("Write failed, closing control connection.\n"));
555 rbuf_uninitialize (&con->rbuf);
559 logputs (LOG_VERBOSE, "\n");
560 logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
563 rbuf_uninitialize (&con->rbuf);
566 case CONPORTERR: case BINDERR: case LISTENERR:
567 /* What now? These problems are local... */
568 logputs (LOG_VERBOSE, "\n");
569 logprintf (LOG_NOTQUIET, _("Bind error (%s).\n"),
575 logputs (LOG_VERBOSE, "\n");
576 logprintf (LOG_NOTQUIET, "%s: %s\n", u->host,
580 rbuf_uninitialize (&con->rbuf);
584 logputs (LOG_VERBOSE, "\n");
585 logputs (LOG_NOTQUIET, _("Invalid PORT.\n"));
588 rbuf_uninitialize (&con->rbuf);
598 if (!opt.server_response)
599 logputs (LOG_VERBOSE, _("done. "));
601 } /* cmd & (DO_LIST | DO_RETR) */
603 /* Restart if needed. */
604 if (restval && (cmd & DO_RETR))
606 if (!opt.server_response)
607 logprintf (LOG_VERBOSE, "==> REST %ld ... ", restval);
608 err = ftp_rest (&con->rbuf, restval);
610 /* FTPRERR, WRITEFAILED, FTPRESTFAIL */
614 logputs (LOG_VERBOSE, "\n");
615 logputs (LOG_NOTQUIET, _("\
616 Error in server response, closing control connection.\n"));
619 rbuf_uninitialize (&con->rbuf);
623 logputs (LOG_VERBOSE, "\n");
624 logputs (LOG_NOTQUIET,
625 _("Write failed, closing control connection.\n"));
628 rbuf_uninitialize (&con->rbuf);
632 /* If `-c' is specified and the file already existed when
633 Wget was started, it would be a bad idea for us to start
634 downloading it from scratch, effectively truncating it. */
635 if (opt.always_rest && (cmd & NO_TRUNCATE))
637 logprintf (LOG_NOTQUIET,
638 _("\nREST failed; will not truncate `%s'.\n"),
642 rbuf_uninitialize (&con->rbuf);
643 return CONTNOTSUPPORTED;
645 logputs (LOG_VERBOSE, _("\nREST failed, starting from scratch.\n"));
655 if (err != FTPRESTFAIL && !opt.server_response)
656 logputs (LOG_VERBOSE, _("done. "));
657 } /* restval && cmd & DO_RETR */
663 if (!opt.server_response)
666 logputs (LOG_VERBOSE, "\n");
667 logprintf (LOG_VERBOSE, "==> RETR %s ... ", u->file);
670 err = ftp_retr (&con->rbuf, u->file);
671 /* FTPRERR, WRITEFAILED, FTPNSFOD */
675 logputs (LOG_VERBOSE, "\n");
676 logputs (LOG_NOTQUIET, _("\
677 Error in server response, closing control connection.\n"));
680 rbuf_uninitialize (&con->rbuf);
684 logputs (LOG_VERBOSE, "\n");
685 logputs (LOG_NOTQUIET,
686 _("Write failed, closing control connection.\n"));
689 rbuf_uninitialize (&con->rbuf);
693 logputs (LOG_VERBOSE, "\n");
694 logprintf (LOG_NOTQUIET, _("No such file `%s'.\n\n"), u->file);
706 if (!opt.server_response)
707 logputs (LOG_VERBOSE, _("done.\n"));
708 expected_bytes = ftp_expected_bytes (ftp_last_respline);
713 if (!opt.server_response)
714 logputs (LOG_VERBOSE, "==> LIST ... ");
715 /* As Maciej W. Rozycki (macro@ds2.pg.gda.pl) says, `LIST'
716 without arguments is better than `LIST .'; confirmed by
718 err = ftp_list (&con->rbuf, NULL);
719 /* FTPRERR, WRITEFAILED */
723 logputs (LOG_VERBOSE, "\n");
724 logputs (LOG_NOTQUIET, _("\
725 Error in server response, closing control connection.\n"));
728 rbuf_uninitialize (&con->rbuf);
732 logputs (LOG_VERBOSE, "\n");
733 logputs (LOG_NOTQUIET,
734 _("Write failed, closing control connection.\n"));
737 rbuf_uninitialize (&con->rbuf);
741 logputs (LOG_VERBOSE, "\n");
742 logprintf (LOG_NOTQUIET, _("No such file or directory `%s'.\n\n"),
754 if (!opt.server_response)
755 logputs (LOG_VERBOSE, _("done.\n"));
756 expected_bytes = ftp_expected_bytes (ftp_last_respline);
757 } /* cmd & DO_LIST */
759 /* Some FTP servers return the total length of file after REST
760 command, others just return the remaining size. */
761 if (*len && restval && expected_bytes
762 && (expected_bytes == *len - restval))
764 DEBUGP (("Lying FTP server found, adjusting.\n"));
765 expected_bytes = *len;
768 /* If no transmission was required, then everything is OK. */
769 if (!(cmd & (DO_LIST | DO_RETR)))
772 if (!passive_mode_open) /* we are not using pasive mode so we need
775 /* Open the data transmission socket by calling acceptport(). */
776 err = acceptport (&dtsock);
777 /* Possible errors: ACCEPTERR. */
778 if (err == ACCEPTERR)
780 logprintf (LOG_NOTQUIET, "accept: %s\n", strerror (errno));
785 /* Open the file -- if opt.dfp is set, use it instead. */
786 if (!opt.dfp || con->cmd & DO_LIST)
788 mkalldirs (u->local);
790 rotate_backups (u->local);
791 /* #### Is this correct? */
792 chmod (u->local, 0600);
794 fp = fopen (u->local, restval ? "ab" : "wb");
797 logprintf (LOG_NOTQUIET, "%s: %s\n", u->local, strerror (errno));
799 rbuf_uninitialize (&con->rbuf);
806 extern int global_download_count;
809 /* Rewind the output document if the download starts over and if
810 this is the first download. See gethttp() for a longer
812 if (!restval && global_download_count == 0)
814 /* This will silently fail for streams that don't correspond
815 to regular files, but that's OK. */
817 /* ftruncate is needed because opt.dfp is opened in append
818 mode if opt.always_rest is set. */
819 ftruncate (fileno (fp), 0);
826 logprintf (LOG_VERBOSE, _("Length: %s"), legible (*len));
828 logprintf (LOG_VERBOSE, _(" [%s to go]"), legible (*len - restval));
829 logputs (LOG_VERBOSE, "\n");
831 else if (expected_bytes)
833 logprintf (LOG_VERBOSE, _("Length: %s"), legible (expected_bytes));
835 logprintf (LOG_VERBOSE, _(" [%s to go]"),
836 legible (expected_bytes - restval));
837 logputs (LOG_VERBOSE, _(" (unauthoritative)\n"));
840 /* Get the contents of the document. */
841 res = get_contents (dtsock, fp, len, restval, expected_bytes, &con->rbuf, 0);
842 con->dltime = elapsed_time ();
843 tms = time_str (NULL);
844 tmrate = rate (*len - restval, con->dltime, 0);
845 /* Close data connection socket. */
847 /* Close the local file. */
849 /* Close or flush the file. We have to be careful to check for
850 error here. Checking the result of fwrite() is not enough --
851 errors could go unnoticed! */
853 if (!opt.dfp || con->cmd & DO_LIST)
854 flush_res = fclose (fp);
856 flush_res = fflush (fp);
857 if (flush_res == EOF)
860 /* If get_contents couldn't write to fp, bail out. */
863 logprintf (LOG_NOTQUIET, _("%s: %s, closing control connection.\n"),
864 u->local, strerror (errno));
866 rbuf_uninitialize (&con->rbuf);
871 logprintf (LOG_NOTQUIET, _("%s (%s) - Data connection: %s; "),
872 tms, tmrate, strerror (errno));
873 if (opt.server_response)
874 logputs (LOG_ALWAYS, "\n");
877 /* Get the server to tell us if everything is retrieved. */
878 err = ftp_response (&con->rbuf, &respline);
879 /* ...and empty the buffer. */
880 rbuf_discard (&con->rbuf);
884 /* The control connection is decidedly closed. Print the time
885 only if it hasn't already been printed. */
887 logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
888 logputs (LOG_NOTQUIET, _("Control connection closed.\n"));
889 /* If there is an error on the control connection, close it, but
890 return FTPRETRINT, since there is a possibility that the
891 whole file was retrieved nevertheless (but that is for
892 ftp_loop_internal to decide). */
894 rbuf_uninitialize (&con->rbuf);
897 /* If retrieval failed for any reason, return FTPRETRINT, but do not
898 close socket, since the control connection is still alive. If
899 there is something wrong with the control connection, it will
900 become apparent later. */
901 if (*respline != '2')
905 logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
906 logputs (LOG_NOTQUIET, _("Data transfer aborted.\n"));
913 /* What now? The data connection was erroneous, whereas the
914 response says everything is OK. We shall play it safe. */
918 if (!(cmd & LEAVE_PENDING))
920 /* I should probably send 'QUIT' and check for a reply, but this
921 is faster. #### Is it OK, though? */
923 rbuf_uninitialize (&con->rbuf);
925 /* If it was a listing, and opt.server_response is true,
927 if (opt.server_response && (con->cmd & DO_LIST))
929 mkalldirs (u->local);
930 fp = fopen (u->local, "r");
932 logprintf (LOG_ALWAYS, "%s: %s\n", u->local, strerror (errno));
936 /* The lines are being read with read_whole_line because of
937 no-buffering on opt.lfile. */
938 while ((line = read_whole_line (fp)))
940 logprintf (LOG_ALWAYS, "%s\n", line);
945 } /* con->cmd & DO_LIST && server_response */
950 /* A one-file FTP loop. This is the part where FTP retrieval is
951 retried, and retried, and retried, and...
953 This loop either gets commands from con, or (if ON_YOUR_OWN is
954 set), makes them up to retrieve the file given by the URL. */
956 ftp_loop_internal (struct urlinfo *u, struct fileinfo *f, ccon *con)
958 int count, orig_lp, no_truncate;
960 char *tms, *tmrate, *locf;
965 u->local = url_filename (u);
967 if (opt.noclobber && file_exists_p (u->local))
969 logprintf (LOG_VERBOSE,
970 _("File `%s' already there, not retrieving.\n"), u->local);
971 /* If the file is there, we suppose it's retrieved OK. */
975 /* Remove it if it's a link. */
976 remove_link (u->local);
977 if (!opt.output_document)
980 locf = opt.output_document;
984 if (con->st & ON_YOUR_OWN)
985 con->st = ON_YOUR_OWN;
987 orig_lp = con->cmd & LEAVE_PENDING ? 1 : 0;
989 /* In `-c' is used, check whether the file we're writing to exists
990 before we've done anything. If so, we'll refuse to truncate it
991 if the server doesn't support continued downloads. */
994 no_truncate = file_exists_p (locf);
999 /* Increment the pass counter. */
1001 sleep_between_retrievals (count);
1002 if (con->st & ON_YOUR_OWN)
1005 con->cmd |= (DO_RETR | LEAVE_PENDING);
1006 if (rbuf_initialized_p (&con->rbuf))
1007 con->cmd &= ~ (DO_LOGIN | DO_CWD);
1009 con->cmd |= (DO_LOGIN | DO_CWD);
1011 else /* not on your own */
1013 if (rbuf_initialized_p (&con->rbuf))
1014 con->cmd &= ~DO_LOGIN;
1016 con->cmd |= DO_LOGIN;
1017 if (con->st & DONE_CWD)
1018 con->cmd &= ~DO_CWD;
1023 con->cmd |= NO_TRUNCATE;
1024 /* Assume no restarting. */
1026 if ((count > 1 || opt.always_rest)
1027 && !(con->cmd & DO_LIST)
1028 && file_exists_p (locf))
1029 if (stat (locf, &st) == 0 && S_ISREG (st.st_mode))
1030 restval = st.st_size;
1031 /* Get the current time string. */
1032 tms = time_str (NULL);
1033 /* Print fetch message, if opt.verbose. */
1036 char *hurl = str_url (u->proxy ? u->proxy : u, 1);
1040 sprintf (tmp, _("(try:%2d)"), count);
1041 logprintf (LOG_VERBOSE, "--%s-- %s\n %s => `%s'\n",
1042 tms, hurl, tmp, locf);
1044 ws_changetitle (hurl, 1);
1048 /* Send getftp the proper length, if fileinfo was provided. */
1053 err = getftp (u, &len, restval, con);
1055 tms = time_str (NULL);
1056 tmrate = rate (len - restval, con->dltime, 0);
1058 if (!rbuf_initialized_p (&con->rbuf))
1059 con->st &= ~DONE_CWD;
1061 con->st |= DONE_CWD;
1065 case HOSTERR: case CONREFUSED: case FWRITEERR: case FOPENERR:
1066 case FTPNSFOD: case FTPLOGINC: case FTPNOPASV: case CONTNOTSUPPORTED:
1067 /* Fatal errors, give up. */
1070 case CONSOCKERR: case CONERROR: case FTPSRVERR: case FTPRERR:
1071 case WRITEFAILED: case FTPUNKNOWNTYPE: case CONPORTERR:
1072 case BINDERR: case LISTENERR: case ACCEPTERR:
1073 case FTPPORTERR: case FTPLOGREFUSED: case FTPINVPASV:
1074 printwhat (count, opt.ntry);
1075 /* non-fatal errors */
1079 /* If the control connection was closed, the retrieval
1080 will be considered OK if f->size == len. */
1081 if (!f || len != f->size)
1083 printwhat (count, opt.ntry);
1095 /* If we get out of the switch above without continue'ing, we've
1096 successfully downloaded a file. Remember this fact. */
1097 downloaded_file(FILE_DOWNLOADED_NORMALLY, locf);
1099 if (con->st & ON_YOUR_OWN)
1101 CLOSE (RBUF_FD (&con->rbuf));
1102 rbuf_uninitialize (&con->rbuf);
1104 logprintf (LOG_VERBOSE, _("%s (%s) - `%s' saved [%ld]\n\n"),
1105 tms, tmrate, locf, len);
1106 if (!opt.verbose && !opt.quiet)
1108 /* Need to hide the password from the URL. The `if' is here
1109 so that we don't do the needless allocation every
1111 char *hurl = str_url (u->proxy ? u->proxy : u, 1);
1112 logprintf (LOG_NONVERBOSE, "%s URL: %s [%ld] -> \"%s\" [%d]\n",
1113 tms, hurl, len, locf, count);
1117 if ((con->cmd & DO_LIST))
1118 /* This is a directory listing file. */
1120 if (!opt.remove_listing)
1121 /* --dont-remove-listing was specified, so do count this towards the
1122 number of bytes and files downloaded. */
1124 downloaded_increase (len);
1128 /* Deletion of listing files is not controlled by --delete-after, but
1129 by the more specific option --dont-remove-listing, and the code
1130 to do this deletion is in another function. */
1133 /* This is not a directory listing file. */
1135 /* Unlike directory listing files, don't pretend normal files weren't
1136 downloaded if they're going to be deleted. People seeding proxies,
1137 for instance, may want to know how many bytes and files they've
1138 downloaded through it. */
1139 downloaded_increase (len);
1142 if (opt.delete_after)
1144 DEBUGP (("Removing file due to --delete-after in"
1145 " ftp_loop_internal():\n"));
1146 logprintf (LOG_VERBOSE, _("Removing %s.\n"), locf);
1148 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1152 /* Restore the original leave-pendingness. */
1154 con->cmd |= LEAVE_PENDING;
1156 con->cmd &= ~LEAVE_PENDING;
1158 } while (!opt.ntry || (count < opt.ntry));
1160 if (rbuf_initialized_p (&con->rbuf) && (con->st & ON_YOUR_OWN))
1162 CLOSE (RBUF_FD (&con->rbuf));
1163 rbuf_uninitialize (&con->rbuf);
1168 /* Return the directory listing in a reusable format. The directory
1169 is specifed in u->dir. */
1171 ftp_get_listing (struct urlinfo *u, ccon *con, struct fileinfo **f)
1174 char *olocal = u->local;
1175 char *list_filename, *ofile;
1177 con->st &= ~ON_YOUR_OWN;
1178 con->cmd |= (DO_LIST | LEAVE_PENDING);
1179 con->cmd &= ~DO_RETR;
1180 /* Get the listing filename. */
1182 u->file = LIST_FILENAME;
1183 list_filename = url_filename (u);
1185 u->local = list_filename;
1186 DEBUGP ((_("Using `%s' as listing tmp file.\n"), list_filename));
1187 err = ftp_loop_internal (u, NULL, con);
1190 *f = ftp_parse_ls (list_filename, con->rs);
1193 if (opt.remove_listing)
1195 if (unlink (list_filename))
1196 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1198 logprintf (LOG_VERBOSE, _("Removed `%s'.\n"), list_filename);
1200 xfree (list_filename);
1201 con->cmd &= ~DO_LIST;
1205 static uerr_t ftp_retrieve_dirs PARAMS ((struct urlinfo *, struct fileinfo *,
1207 static uerr_t ftp_retrieve_glob PARAMS ((struct urlinfo *, ccon *, int));
1208 static struct fileinfo *delelement PARAMS ((struct fileinfo *,
1209 struct fileinfo **));
1210 static void freefileinfo PARAMS ((struct fileinfo *f));
1212 /* Retrieve a list of files given in struct fileinfo linked list. If
1213 a file is a symbolic link, do not retrieve it, but rather try to
1214 set up a similar link on the local disk, if the symlinks are
1217 If opt.recursive is set, after all files have been retrieved,
1218 ftp_retrieve_dirs will be called to retrieve the directories. */
1220 ftp_retrieve_list (struct urlinfo *u, struct fileinfo *f, ccon *con)
1222 static int depth = 0;
1224 char *olocal, *ofile;
1225 struct fileinfo *orig;
1230 /* Increase the depth. */
1232 if (opt.reclevel != INFINITE_RECURSION && depth > opt.reclevel)
1234 DEBUGP ((_("Recursion depth %d exceeded max. depth %d.\n"),
1235 depth, opt.reclevel));
1243 con->st &= ~ON_YOUR_OWN;
1244 if (!(con->st & DONE_CWD))
1247 con->cmd &= ~DO_CWD;
1248 con->cmd |= (DO_RETR | LEAVE_PENDING);
1250 if (!rbuf_initialized_p (&con->rbuf))
1251 con->cmd |= DO_LOGIN;
1253 con->cmd &= ~DO_LOGIN;
1255 err = RETROK; /* in case it's not used */
1259 if (downloaded_exceeds_quota ())
1267 u->local = url_filename (u);
1271 if (opt.timestamping && f->type == FT_PLAINFILE)
1274 /* If conversion of HTML files retrieved via FTP is ever implemented,
1275 we'll need to stat() <file>.orig here when -K has been specified.
1276 I'm not implementing it now since files on an FTP server are much
1277 more likely than files on an HTTP server to legitimately have a
1279 if (!stat (u->local, &st))
1283 /* Else, get it from the file. */
1284 local_size = st.st_size;
1286 /* Compare file sizes only for servers that tell us correct
1287 values. Assumme sizes being equal for servers that lie
1289 cor_val = (con->rs == ST_UNIX || con->rs == ST_WINNT);
1290 eq_size = cor_val ? (local_size == f->size) : 1 ;
1291 if (f->tstamp <= tml && eq_size)
1293 /* Remote file is older, file sizes can be compared and
1295 logprintf (LOG_VERBOSE, _("\
1296 Remote file no newer than local file `%s' -- not retrieving.\n"), u->local);
1301 /* Remote file is newer or sizes cannot be matched */
1302 logprintf (LOG_VERBOSE, _("\
1303 Remote file is newer than local file `%s' -- retrieving.\n\n"),
1308 /* Sizes do not match */
1309 logprintf (LOG_VERBOSE, _("\
1310 The sizes do not match (local %ld) -- retrieving.\n\n"), local_size);
1313 } /* opt.timestamping && f->type == FT_PLAINFILE */
1317 /* If opt.retr_symlinks is defined, we treat symlinks as
1318 if they were normal files. There is currently no way
1319 to distinguish whether they might be directories, and
1321 if (!opt.retr_symlinks)
1325 logputs (LOG_NOTQUIET,
1326 _("Invalid name of the symlink, skipping.\n"));
1330 /* Check whether we already have the correct
1332 int rc = lstat (u->local, &st);
1335 size_t len = strlen (f->linkto) + 1;
1336 if (S_ISLNK (st.st_mode))
1338 char *link_target = (char *)alloca (len);
1339 size_t n = readlink (u->local, link_target, len);
1341 && (memcmp (link_target, f->linkto, n) == 0))
1343 logprintf (LOG_VERBOSE, _("\
1344 Already have correct symlink %s -> %s\n\n"),
1345 u->local, f->linkto);
1351 logprintf (LOG_VERBOSE, _("Creating symlink %s -> %s\n"),
1352 u->local, f->linkto);
1353 /* Unlink before creating symlink! */
1355 if (symlink (f->linkto, u->local) == -1)
1356 logprintf (LOG_NOTQUIET, "symlink: %s\n",
1358 logputs (LOG_VERBOSE, "\n");
1359 } /* have f->linkto */
1360 #else /* not HAVE_SYMLINK */
1361 logprintf (LOG_NOTQUIET,
1362 _("Symlinks not supported, skipping symlink `%s'.\n"),
1364 #endif /* not HAVE_SYMLINK */
1366 else /* opt.retr_symlinks */
1369 err = ftp_loop_internal (u, f, con);
1370 } /* opt.retr_symlinks */
1374 logprintf (LOG_NOTQUIET, _("Skipping directory `%s'.\n"),
1378 /* Call the retrieve loop. */
1380 err = ftp_loop_internal (u, f, con);
1383 logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
1388 /* Set the time-stamp information to the local file. Symlinks
1389 are not to be stamped because it sets the stamp on the
1391 if (!(f->type == FT_SYMLINK && !opt.retr_symlinks)
1394 && file_exists_p (u->local))
1396 /* #### This code repeats in http.c and ftp.c. Move it to a
1398 const char *fl = NULL;
1399 if (opt.output_document)
1401 if (opt.od_known_regular)
1402 fl = opt.output_document;
1407 touch (fl, f->tstamp);
1409 else if (f->tstamp == -1)
1410 logprintf (LOG_NOTQUIET, _("%s: corrupt time-stamp.\n"), u->local);
1412 if (f->perms && f->type == FT_PLAINFILE && dlthis)
1413 chmod (u->local, f->perms);
1415 DEBUGP (("Unrecognized permissions for %s.\n", u->local));
1420 /* Break on fatals. */
1421 if (err == QUOTEXC || err == HOSTERR || err == FWRITEERR)
1423 con->cmd &= ~ (DO_CWD | DO_LOGIN);
1426 /* We do not want to call ftp_retrieve_dirs here */
1427 if (opt.recursive &&
1428 !(opt.reclevel != INFINITE_RECURSION && depth >= opt.reclevel))
1429 err = ftp_retrieve_dirs (u, orig, con);
1430 else if (opt.recursive)
1431 DEBUGP ((_("Will not retrieve dirs since depth is %d (max %d).\n"),
1432 depth, opt.reclevel));
1437 /* Retrieve the directories given in a file list. This function works
1438 by simply going through the linked list and calling
1439 ftp_retrieve_glob on each directory entry. The function knows
1440 about excluded directories. */
1442 ftp_retrieve_dirs (struct urlinfo *u, struct fileinfo *f, ccon *con)
1445 char *current_container = NULL;
1446 int current_length = 0;
1448 for (; f; f = f->next)
1452 if (downloaded_exceeds_quota ())
1454 if (f->type != FT_DIRECTORY)
1457 len = strlen (u->dir) + 1 + strlen (f->name) + 1;
1458 /* Allocate u->dir off stack, but reallocate only if a larger
1459 string is needed. */
1460 if (len > current_length)
1461 current_container = (char *)alloca (len);
1462 u->dir = current_container;
1463 sprintf (u->dir, "%s%s%s", odir,
1464 (*odir == '/' && !*(odir + 1)) ? "" : "/", f->name);
1465 if (!accdir (u->dir, ALLABS))
1467 logprintf (LOG_VERBOSE, _("\
1468 Not descending to `%s' as it is excluded/not-included.\n"), u->dir);
1472 con->st &= ~DONE_CWD;
1473 ftp_retrieve_glob (u, con, GETALL);
1474 /* Set the time-stamp? */
1477 if (opt.quota && opt.downloaded > opt.quota)
1484 /* A near-top-level function to retrieve the files in a directory.
1485 The function calls ftp_get_listing, to get a linked list of files.
1486 Then it weeds out the file names that do not match the pattern.
1487 ftp_retrieve_list is called with this updated list as an argument.
1489 If the argument ACTION is GETONE, just download the file (but first
1490 get the listing, so that the time-stamp is heeded); if it's GLOBALL,
1491 use globbing; if it's GETALL, download the whole directory. */
1493 ftp_retrieve_glob (struct urlinfo *u, ccon *con, int action)
1495 struct fileinfo *orig, *start;
1498 con->cmd |= LEAVE_PENDING;
1500 res = ftp_get_listing (u, con, &orig);
1504 /* First: weed out that do not conform the global rules given in
1505 opt.accepts and opt.rejects. */
1506 if (opt.accepts || opt.rejects)
1508 struct fileinfo *f = orig;
1512 if (f->type != FT_DIRECTORY && !acceptable (f->name))
1514 logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"), f->name);
1515 f = delelement (f, &start);
1521 /* Now weed out the files that do not match our globbing pattern.
1522 If we are dealing with a globbing pattern, that is. */
1523 if (*u->file && (action == GLOBALL || action == GETONE))
1526 struct fileinfo *f = start;
1530 matchres = fnmatch (u->file, f->name, 0);
1533 logprintf (LOG_NOTQUIET, "%s: %s\n", u->local,
1537 if (matchres == FNM_NOMATCH)
1538 f = delelement (f, &start); /* delete the element from the list */
1540 f = f->next; /* leave the element in the list */
1544 freefileinfo (start);
1545 return RETRBADPATTERN;
1551 /* Just get everything. */
1552 ftp_retrieve_list (u, start, con);
1556 if (action == GLOBALL)
1559 /* #### This message SUCKS. We should see what was the
1560 reason that nothing was retrieved. */
1561 logprintf (LOG_VERBOSE, _("No matches on pattern `%s'.\n"), u->file);
1563 else /* GETONE or GETALL */
1565 /* Let's try retrieving it anyway. */
1566 con->st |= ON_YOUR_OWN;
1567 res = ftp_loop_internal (u, NULL, con);
1571 freefileinfo (start);
1572 if (downloaded_exceeds_quota ())
1575 /* #### Should we return `res' here? */
1579 /* The wrapper that calls an appropriate routine according to contents
1580 of URL. Inherently, its capabilities are limited on what can be
1581 encoded into a URL. */
1583 ftp_loop (struct urlinfo *u, int *dt)
1585 ccon con; /* FTP connection */
1590 memset (&con, 0, sizeof (con));
1592 rbuf_uninitialize (&con.rbuf);
1593 con.st = ON_YOUR_OWN;
1596 res = RETROK; /* in case it's not used */
1598 /* If the file name is empty, the user probably wants a directory
1599 index. We'll provide one, properly HTML-ized. Unless
1600 opt.htmlify is 0, of course. :-) */
1601 if (!*u->file && !opt.recursive)
1604 res = ftp_get_listing (u, &con, &f);
1610 char *filename = (opt.output_document
1611 ? xstrdup (opt.output_document)
1612 : (u->local ? xstrdup (u->local)
1613 : url_filename (u)));
1614 res = ftp_index (filename, u, f);
1615 if (res == FTPOK && opt.verbose)
1617 if (!opt.output_document)
1621 if (stat (filename, &st) == 0)
1625 logprintf (LOG_NOTQUIET,
1626 _("Wrote HTML-ized index to `%s' [%ld].\n"),
1630 logprintf (LOG_NOTQUIET,
1631 _("Wrote HTML-ized index to `%s'.\n"),
1641 int wild = has_wildcards_p (u->file);
1642 if ((opt.ftp_glob && wild) || opt.recursive || opt.timestamping)
1644 /* ftp_retrieve_glob is a catch-all function that gets called
1645 if we need globbing, time-stamping or recursion. Its
1646 third argument is just what we really need. */
1647 ftp_retrieve_glob (u, &con,
1648 (opt.ftp_glob && wild) ? GLOBALL : GETONE);
1651 res = ftp_loop_internal (u, NULL, &con);
1657 /* If a connection was left, quench it. */
1658 if (rbuf_initialized_p (&con.rbuf))
1659 CLOSE (RBUF_FD (&con.rbuf));
1660 FREE_MAYBE (con.id);
1665 /* Delete an element from the fileinfo linked list. Returns the
1666 address of the next element, or NULL if the list is exhausted. It
1667 can modify the start of the list. */
1668 static struct fileinfo *
1669 delelement (struct fileinfo *f, struct fileinfo **start)
1671 struct fileinfo *prev = f->prev;
1672 struct fileinfo *next = f->next;
1675 FREE_MAYBE (f->linkto);
1687 /* Free the fileinfo linked list of files. */
1689 freefileinfo (struct fileinfo *f)
1693 struct fileinfo *next = f->next;