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. */
33 #include <sys/types.h>
55 /* File where the "ls -al" listing will be saved. */
56 #define LIST_FILENAME ".listing"
58 extern char ftp_last_respline[];
60 /* #### Global variables?? These two should be members of struct
63 static enum stype host_type=ST_UNIX;
66 /* Look for regexp "( *[0-9]+ *byte" (literal parenthesis) anywhere in
67 the string S, and return the number converted to long, if found, 0
70 ftp_expected_bytes (const char *s)
76 while (*s && *s != '(')
80 for (++s; *s && ISSPACE (*s); s++);
88 res = (*s - '0') + 10 * res;
91 while (*s && ISDIGIT (*s));
94 while (*s && ISSPACE (*s))
98 if (TOLOWER (*s) != 'b')
100 if (strncasecmp (s, "byte", 4))
108 /* Retrieves a file with denoted parameters through opening an FTP
109 connection to the server. It always closes the data connection,
110 and closes the control connection in case of error. */
112 getftp (const struct urlinfo *u, long *len, long restval, ccon *con)
114 int csock, dtsock, res;
117 char *user, *passwd, *respline;
119 unsigned char pasv_addr[6];
121 int passive_mode_open = 0;
122 long expected_bytes = 0L;
124 assert (con != NULL);
125 assert (u->local != NULL);
126 /* Debug-check of the sanity of the request by making sure that LIST
127 and RETR are never both requested (since we can handle only one
129 assert (!((cmd & DO_LIST) && (cmd & DO_RETR)));
130 /* Make sure that at least *something* is requested. */
131 assert ((cmd & (DO_LIST | DO_CWD | DO_RETR | DO_LOGIN)) != 0);
135 search_netrc (u->host, (const char **)&user, (const char **)&passwd, 1);
136 user = user ? user : opt.ftp_acc;
138 opt.ftp_pass = ftp_getaddress ();
139 passwd = passwd ? passwd : opt.ftp_pass;
140 assert (user && passwd);
145 if (!(cmd & DO_LOGIN))
146 csock = RBUF_FD (&con->rbuf);
147 else /* cmd & DO_LOGIN */
149 /* Login to the server: */
151 /* First: Establish the control connection. */
152 logprintf (LOG_VERBOSE, _("Connecting to %s:%hu... "), u->host, u->port);
153 err = make_connection (&csock, u->host, u->port);
154 if (cmd & LEAVE_PENDING)
155 rbuf_initialize (&con->rbuf, csock);
157 rbuf_uninitialize (&con->rbuf);
160 /* Do not close the socket in first several cases, since it
161 wasn't created at all. */
163 logputs (LOG_VERBOSE, "\n");
164 logprintf (LOG_NOTQUIET, "%s: %s\n", u->host, herrmsg (h_errno));
168 logputs (LOG_VERBOSE, "\n");
169 logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
173 logputs (LOG_VERBOSE, "\n");
174 logprintf (LOG_NOTQUIET, _("Connection to %s:%hu refused.\n"),
177 rbuf_uninitialize (&con->rbuf);
180 logputs (LOG_VERBOSE, "\n");
181 logprintf (LOG_NOTQUIET, "connect: %s\n", strerror (errno));
183 rbuf_uninitialize (&con->rbuf);
190 /* Since this is a new connection, we may safely discard
191 anything left in the buffer. */
192 rbuf_discard (&con->rbuf);
194 /* Second: Login with proper USER/PASS sequence. */
195 logputs (LOG_VERBOSE, _("connected!\n"));
196 logprintf (LOG_VERBOSE, _("Logging in as %s ... "), user);
197 if (opt.server_response)
198 logputs (LOG_ALWAYS, "\n");
199 err = ftp_login (&con->rbuf, user, passwd);
200 /* FTPRERR, FTPSRVERR, WRITEFAILED, FTPLOGREFUSED, FTPLOGINC */
204 logputs (LOG_VERBOSE, "\n");
205 logputs (LOG_NOTQUIET, _("\
206 Error in server response, closing control connection.\n"));
208 rbuf_uninitialize (&con->rbuf);
212 logputs (LOG_VERBOSE, "\n");
213 logputs (LOG_NOTQUIET, _("Error in server greeting.\n"));
215 rbuf_uninitialize (&con->rbuf);
219 logputs (LOG_VERBOSE, "\n");
220 logputs (LOG_NOTQUIET,
221 _("Write failed, closing control connection.\n"));
223 rbuf_uninitialize (&con->rbuf);
227 logputs (LOG_VERBOSE, "\n");
228 logputs (LOG_NOTQUIET, _("The server refuses login.\n"));
230 rbuf_uninitialize (&con->rbuf);
231 return FTPLOGREFUSED;
234 logputs (LOG_VERBOSE, "\n");
235 logputs (LOG_NOTQUIET, _("Login incorrect.\n"));
237 rbuf_uninitialize (&con->rbuf);
241 if (!opt.server_response)
242 logputs (LOG_VERBOSE, _("Logged in!\n"));
249 /* Third: Get the system type */
250 if (!opt.server_response)
251 logprintf (LOG_VERBOSE, "==> SYST ... ");
252 err = ftp_syst (&con->rbuf, &host_type);
257 logputs (LOG_VERBOSE, "\n");
258 logputs (LOG_NOTQUIET, _("\
259 Error in server response, closing control connection.\n"));
261 rbuf_uninitialize (&con->rbuf);
265 logputs (LOG_VERBOSE, "\n");
266 logputs (LOG_NOTQUIET,
267 _("Server error, can't determine system type.\n"));
270 /* Everything is OK. */
276 if (!opt.server_response)
277 logputs (LOG_VERBOSE, _("done. "));
279 /* Fourth: Find the initial ftp directory */
281 if (!opt.server_response)
282 logprintf (LOG_VERBOSE, "==> PWD ... ");
283 err = ftp_pwd(&con->rbuf, &pwd);
287 case FTPRERR || FTPSRVERR :
288 logputs (LOG_VERBOSE, "\n");
289 logputs (LOG_NOTQUIET, _("\
290 Error in server response, closing control connection.\n"));
292 rbuf_uninitialize (&con->rbuf);
296 /* Everything is OK. */
302 if (!opt.server_response)
303 logputs (LOG_VERBOSE, _("done.\n"));
305 /* Fifth: Set the FTP type. */
306 if (!opt.server_response)
307 logprintf (LOG_VERBOSE, "==> TYPE %c ... ", TOUPPER (u->ftp_type));
308 err = ftp_type (&con->rbuf, TOUPPER (u->ftp_type));
309 /* FTPRERR, WRITEFAILED, FTPUNKNOWNTYPE */
313 logputs (LOG_VERBOSE, "\n");
314 logputs (LOG_NOTQUIET, _("\
315 Error in server response, closing control connection.\n"));
317 rbuf_uninitialize (&con->rbuf);
321 logputs (LOG_VERBOSE, "\n");
322 logputs (LOG_NOTQUIET,
323 _("Write failed, closing control connection.\n"));
325 rbuf_uninitialize (&con->rbuf);
329 logputs (LOG_VERBOSE, "\n");
330 logprintf (LOG_NOTQUIET,
331 _("Unknown type `%c', closing control connection.\n"),
332 TOUPPER (u->ftp_type));
334 rbuf_uninitialize (&con->rbuf);
337 /* Everything is OK. */
343 if (!opt.server_response)
344 logputs (LOG_VERBOSE, _("done. "));
350 logputs (LOG_VERBOSE, _("==> CWD not needed.\n"));
353 /* Change working directory. If the FTP host runs VMS and
354 the path specified is absolute, we will have to convert
355 it to VMS style as VMS does not like leading slashes */
356 DEBUGP (("changing working directory\n"));
357 if (*(u->dir) == '/')
359 int pwd_len = strlen (pwd);
360 char *result = (char *)alloca (strlen (u->dir) + pwd_len + 10);
366 char *tmp_dir, *tmpp;
367 STRDUP_ALLOCA (tmp_dir, u->dir);
368 for (tmpp = tmp_dir; *tmpp; tmpp++)
371 strcpy (result, pwd);
372 /* pwd ends with ']', we have to get rid of it */
373 result[pwd_len - 1]= '\0';
374 strcat (result, tmp_dir);
375 strcat (result, "]");
380 /* pwd_len == 1 means pwd = "/", but u->dir begins with '/'
383 strcpy (result, pwd);
384 strcat (result, u->dir);
385 /* These look like debugging messages to me. */
387 logprintf (LOG_VERBOSE, "\npwd=\"%s\"", pwd);
388 logprintf (LOG_VERBOSE, "\nu->dir=\"%s\"", u->dir);
395 if (!opt.server_response)
396 logprintf (LOG_VERBOSE, "==> CWD %s ... ", result);
397 err = ftp_cwd (&con->rbuf, result);
401 if (!opt.server_response)
402 logprintf (LOG_VERBOSE, "==> CWD %s ... ", u->dir);
403 err = ftp_cwd (&con->rbuf, u->dir);
405 /* FTPRERR, WRITEFAILED, FTPNSFOD */
409 logputs (LOG_VERBOSE, "\n");
410 logputs (LOG_NOTQUIET, _("\
411 Error in server response, closing control connection.\n"));
413 rbuf_uninitialize (&con->rbuf);
417 logputs (LOG_VERBOSE, "\n");
418 logputs (LOG_NOTQUIET,
419 _("Write failed, closing control connection.\n"));
421 rbuf_uninitialize (&con->rbuf);
425 logputs (LOG_VERBOSE, "\n");
426 logprintf (LOG_NOTQUIET, _("No such directory `%s'.\n\n"),
429 rbuf_uninitialize (&con->rbuf);
439 if (!opt.server_response)
440 logputs (LOG_VERBOSE, _("done.\n"));
443 else /* do not CWD */
444 logputs (LOG_VERBOSE, _("==> CWD not required.\n"));
446 /* If anything is to be retrieved, PORT (or PASV) must be sent. */
447 if (cmd & (DO_LIST | DO_RETR))
449 if (opt.ftp_pasv > 0)
452 unsigned short tport;
454 if (!opt.server_response)
455 logputs (LOG_VERBOSE, "==> PASV ... ");
456 err = ftp_pasv (&con->rbuf, pasv_addr);
457 /* FTPRERR, WRITEFAILED, FTPNOPASV, FTPINVPASV */
461 logputs (LOG_VERBOSE, "\n");
462 logputs (LOG_NOTQUIET, _("\
463 Error in server response, closing control connection.\n"));
465 rbuf_uninitialize (&con->rbuf);
469 logputs (LOG_VERBOSE, "\n");
470 logputs (LOG_NOTQUIET,
471 _("Write failed, closing control connection.\n"));
473 rbuf_uninitialize (&con->rbuf);
477 logputs (LOG_VERBOSE, "\n");
478 logputs (LOG_NOTQUIET, _("Cannot initiate PASV transfer.\n"));
481 logputs (LOG_VERBOSE, "\n");
482 logputs (LOG_NOTQUIET, _("Cannot parse PASV response.\n"));
493 sprintf (thost, "%d.%d.%d.%d",
494 pasv_addr[0], pasv_addr[1], pasv_addr[2], pasv_addr[3]);
495 tport = (pasv_addr[4] << 8) + pasv_addr[5];
496 DEBUGP ((_("Will try connecting to %s:%hu.\n"), thost, tport));
497 err = make_connection (&dtsock, thost, tport);
500 /* Do not close the socket in first several cases,
501 since it wasn't created at all. */
503 logputs (LOG_VERBOSE, "\n");
504 logprintf (LOG_NOTQUIET, "%s: %s\n", thost,
507 rbuf_uninitialize (&con->rbuf);
511 logputs (LOG_VERBOSE, "\n");
512 logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
514 rbuf_uninitialize (&con->rbuf);
518 logputs (LOG_VERBOSE, "\n");
519 logprintf (LOG_NOTQUIET,
520 _("Connection to %s:%hu refused.\n"),
523 rbuf_uninitialize (&con->rbuf);
527 logputs (LOG_VERBOSE, "\n");
528 logprintf (LOG_NOTQUIET, "connect: %s\n",
531 rbuf_uninitialize (&con->rbuf);
539 passive_mode_open= 1; /* Flag to avoid accept port */
540 if (!opt.server_response)
541 logputs (LOG_VERBOSE, _("done. "));
545 if (!passive_mode_open) /* Try to use a port command if PASV failed */
547 if (!opt.server_response)
548 logputs (LOG_VERBOSE, "==> PORT ... ");
549 err = ftp_port (&con->rbuf);
550 /* FTPRERR, WRITEFAILED, bindport (CONSOCKERR, CONPORTERR, BINDERR,
551 LISTENERR), HOSTERR, FTPPORTERR */
555 logputs (LOG_VERBOSE, "\n");
556 logputs (LOG_NOTQUIET, _("\
557 Error in server response, closing control connection.\n"));
560 rbuf_uninitialize (&con->rbuf);
564 logputs (LOG_VERBOSE, "\n");
565 logputs (LOG_NOTQUIET,
566 _("Write failed, closing control connection.\n"));
569 rbuf_uninitialize (&con->rbuf);
573 logputs (LOG_VERBOSE, "\n");
574 logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
577 rbuf_uninitialize (&con->rbuf);
580 case CONPORTERR: case BINDERR: case LISTENERR:
581 /* What now? These problems are local... */
582 logputs (LOG_VERBOSE, "\n");
583 logprintf (LOG_NOTQUIET, _("Bind error (%s).\n"),
589 logputs (LOG_VERBOSE, "\n");
590 logprintf (LOG_NOTQUIET, "%s: %s\n", u->host,
594 rbuf_uninitialize (&con->rbuf);
598 logputs (LOG_VERBOSE, "\n");
599 logputs (LOG_NOTQUIET, _("Invalid PORT.\n"));
602 rbuf_uninitialize (&con->rbuf);
612 if (!opt.server_response)
613 logputs (LOG_VERBOSE, _("done. "));
615 } /* cmd & (DO_LIST | DO_RETR) */
617 /* Restart if needed. */
618 if (restval && (cmd & DO_RETR))
620 if (!opt.server_response)
621 logprintf (LOG_VERBOSE, "==> REST %ld ... ", restval);
622 err = ftp_rest (&con->rbuf, restval);
624 /* FTPRERR, WRITEFAILED, FTPRESTFAIL */
628 logputs (LOG_VERBOSE, "\n");
629 logputs (LOG_NOTQUIET, _("\
630 Error in server response, closing control connection.\n"));
633 rbuf_uninitialize (&con->rbuf);
637 logputs (LOG_VERBOSE, "\n");
638 logputs (LOG_NOTQUIET,
639 _("Write failed, closing control connection.\n"));
642 rbuf_uninitialize (&con->rbuf);
646 logputs (LOG_VERBOSE, _("\nREST failed, starting from scratch.\n"));
656 if (err != FTPRESTFAIL && !opt.server_response)
657 logputs (LOG_VERBOSE, _("done. "));
658 } /* restval && cmd & DO_RETR */
664 if (!opt.server_response)
667 logputs (LOG_VERBOSE, "\n");
668 logprintf (LOG_VERBOSE, "==> RETR %s ... ", u->file);
671 err = ftp_retr (&con->rbuf, u->file);
672 /* FTPRERR, WRITEFAILED, FTPNSFOD */
676 logputs (LOG_VERBOSE, "\n");
677 logputs (LOG_NOTQUIET, _("\
678 Error in server response, closing control connection.\n"));
681 rbuf_uninitialize (&con->rbuf);
685 logputs (LOG_VERBOSE, "\n");
686 logputs (LOG_NOTQUIET,
687 _("Write failed, closing control connection.\n"));
690 rbuf_uninitialize (&con->rbuf);
694 logputs (LOG_VERBOSE, "\n");
695 logprintf (LOG_NOTQUIET, _("No such file `%s'.\n\n"), u->file);
707 if (!opt.server_response)
708 logputs (LOG_VERBOSE, _("done.\n"));
709 expected_bytes = ftp_expected_bytes (ftp_last_respline);
714 if (!opt.server_response)
715 logputs (LOG_VERBOSE, "==> LIST ... ");
716 /* As Maciej W. Rozycki (macro@ds2.pg.gda.pl) says, `LIST'
717 without arguments is better than `LIST .'; confirmed by
719 err = ftp_list (&con->rbuf, NULL);
720 /* FTPRERR, WRITEFAILED */
724 logputs (LOG_VERBOSE, "\n");
725 logputs (LOG_NOTQUIET, _("\
726 Error in server response, closing control connection.\n"));
729 rbuf_uninitialize (&con->rbuf);
733 logputs (LOG_VERBOSE, "\n");
734 logputs (LOG_NOTQUIET,
735 _("Write failed, closing control connection.\n"));
738 rbuf_uninitialize (&con->rbuf);
742 logputs (LOG_VERBOSE, "\n");
743 logprintf (LOG_NOTQUIET, _("No such file or directory `%s'.\n\n"),
755 if (!opt.server_response)
756 logputs (LOG_VERBOSE, _("done.\n"));
757 expected_bytes = ftp_expected_bytes (ftp_last_respline);
758 } /* cmd & DO_LIST */
760 /* Some FTP servers return the total length of file after REST
761 command, others just return the remaining size. */
762 if (*len && restval && expected_bytes
763 && (expected_bytes == *len - restval))
765 DEBUGP (("Lying FTP server found, adjusting.\n"));
766 expected_bytes = *len;
769 /* If no transmission was required, then everything is OK. */
770 if (!(cmd & (DO_LIST | DO_RETR)))
773 if (!passive_mode_open) /* we are not using pasive mode so we need
776 /* Open the data transmission socket by calling acceptport(). */
777 err = acceptport (&dtsock);
778 /* Possible errors: ACCEPTERR. */
779 if (err == ACCEPTERR)
781 logprintf (LOG_NOTQUIET, "accept: %s\n", strerror (errno));
786 /* Open the file -- if opt.dfp is set, use it instead. */
787 if (!opt.dfp || con->cmd & DO_LIST)
789 mkalldirs (u->local);
791 rotate_backups (u->local);
792 /* #### Is this correct? */
793 chmod (u->local, 0600);
795 fp = fopen (u->local, restval ? "ab" : "wb");
798 logprintf (LOG_NOTQUIET, "%s: %s\n", u->local, strerror (errno));
800 rbuf_uninitialize (&con->rbuf);
810 /* This will silently fail for streams that don't correspond
811 to regular files, but that's OK. */
819 logprintf (LOG_VERBOSE, _("Length: %s"), legible (*len));
821 logprintf (LOG_VERBOSE, _(" [%s to go]"), legible (*len - restval));
822 logputs (LOG_VERBOSE, "\n");
824 else if (expected_bytes)
826 logprintf (LOG_VERBOSE, _("Length: %s"), legible (expected_bytes));
828 logprintf (LOG_VERBOSE, _(" [%s to go]"),
829 legible (expected_bytes - restval));
830 logputs (LOG_VERBOSE, _(" (unauthoritative)\n"));
833 /* Get the contents of the document. */
834 res = get_contents (dtsock, fp, len, restval, expected_bytes, &con->rbuf, 0);
835 con->dltime = elapsed_time ();
836 tms = time_str (NULL);
837 tmrate = rate (*len - restval, con->dltime);
838 /* Close data connection socket. */
840 /* Close the local file. */
842 /* Close or flush the file. We have to be careful to check for
843 error here. Checking the result of fwrite() is not enough --
844 errors could go unnoticed! */
846 if (!opt.dfp || con->cmd & DO_LIST)
847 flush_res = fclose (fp);
849 flush_res = fflush (fp);
850 if (flush_res == EOF)
853 /* If get_contents couldn't write to fp, bail out. */
856 logprintf (LOG_NOTQUIET, _("%s: %s, closing control connection.\n"),
857 u->local, strerror (errno));
859 rbuf_uninitialize (&con->rbuf);
864 logprintf (LOG_NOTQUIET, _("%s (%s) - Data connection: %s; "),
865 tms, tmrate, strerror (errno));
866 if (opt.server_response)
867 logputs (LOG_ALWAYS, "\n");
870 /* Get the server to tell us if everything is retrieved. */
871 err = ftp_response (&con->rbuf, &respline);
872 /* ...and empty the buffer. */
873 rbuf_discard (&con->rbuf);
877 /* The control connection is decidedly closed. Print the time
878 only if it hasn't already been printed. */
880 logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
881 logputs (LOG_NOTQUIET, _("Control connection closed.\n"));
882 /* If there is an error on the control connection, close it, but
883 return FTPRETRINT, since there is a possibility that the
884 whole file was retrieved nevertheless (but that is for
885 ftp_loop_internal to decide). */
887 rbuf_uninitialize (&con->rbuf);
890 /* If retrieval failed for any reason, return FTPRETRINT, but do not
891 close socket, since the control connection is still alive. If
892 there is something wrong with the control connection, it will
893 become apparent later. */
894 if (*respline != '2')
898 logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
899 logputs (LOG_NOTQUIET, _("Data transfer aborted.\n"));
906 /* What now? The data connection was erroneous, whereas the
907 response says everything is OK. We shall play it safe. */
911 if (!(cmd & LEAVE_PENDING))
913 /* I should probably send 'QUIT' and check for a reply, but this
914 is faster. #### Is it OK, though? */
916 rbuf_uninitialize (&con->rbuf);
918 /* If it was a listing, and opt.server_response is true,
920 if (opt.server_response && (con->cmd & DO_LIST))
922 mkalldirs (u->local);
923 fp = fopen (u->local, "r");
925 logprintf (LOG_ALWAYS, "%s: %s\n", u->local, strerror (errno));
929 /* The lines are being read with read_whole_line because of
930 no-buffering on opt.lfile. */
931 while ((line = read_whole_line (fp)))
933 logprintf (LOG_ALWAYS, "%s\n", line);
938 } /* con->cmd & DO_LIST && server_response */
943 /* A one-file FTP loop. This is the part where FTP retrieval is
944 retried, and retried, and retried, and...
946 This loop either gets commands from con, or (if ON_YOUR_OWN is
947 set), makes them up to retrieve the file given by the URL. */
949 ftp_loop_internal (struct urlinfo *u, struct fileinfo *f, ccon *con)
951 static int first_retrieval = 1;
955 char *tms, *tmrate, *locf;
960 u->local = url_filename (u);
962 if (opt.noclobber && file_exists_p (u->local))
964 logprintf (LOG_VERBOSE,
965 _("File `%s' already there, not retrieving.\n"), u->local);
966 /* If the file is there, we suppose it's retrieved OK. */
970 /* Remove it if it's a link. */
971 remove_link (u->local);
972 if (!opt.output_document)
975 locf = opt.output_document;
979 if (con->st & ON_YOUR_OWN)
980 con->st = ON_YOUR_OWN;
982 orig_lp = con->cmd & LEAVE_PENDING ? 1 : 0;
987 /* Increment the pass counter. */
989 /* Wait before the retrieval (unless this is the very first
991 Check if we are retrying or not, wait accordingly - HEH */
992 if (!first_retrieval && (opt.wait || (count && opt.waitretry)))
996 if (count<opt.waitretry)
999 sleep(opt.waitretry);
1004 if (first_retrieval)
1005 first_retrieval = 0;
1006 if (con->st & ON_YOUR_OWN)
1009 con->cmd |= (DO_RETR | LEAVE_PENDING);
1010 if (rbuf_initialized_p (&con->rbuf))
1011 con->cmd &= ~ (DO_LOGIN | DO_CWD);
1013 con->cmd |= (DO_LOGIN | DO_CWD);
1015 else /* not on your own */
1017 if (rbuf_initialized_p (&con->rbuf))
1018 con->cmd &= ~DO_LOGIN;
1020 con->cmd |= DO_LOGIN;
1021 if (con->st & DONE_CWD)
1022 con->cmd &= ~DO_CWD;
1026 /* Assume no restarting. */
1028 if ((count > 1 || opt.always_rest)
1029 && !(con->cmd & DO_LIST)
1030 && file_exists_p (u->local))
1031 if (stat (u->local, &st) == 0)
1032 restval = st.st_size;
1033 /* Get the current time string. */
1034 tms = time_str (NULL);
1035 /* Print fetch message, if opt.verbose. */
1038 char *hurl = str_url (u->proxy ? u->proxy : u, 1);
1042 sprintf (tmp, _("(try:%2d)"), count);
1043 logprintf (LOG_VERBOSE, "--%s-- %s\n %s => `%s'\n",
1044 tms, hurl, tmp, locf);
1046 ws_changetitle (hurl, 1);
1050 /* Send getftp the proper length, if fileinfo was provided. */
1055 err = getftp (u, &len, restval, con);
1057 tms = time_str (NULL);
1058 tmrate = rate (len - restval, con->dltime);
1060 if (!rbuf_initialized_p (&con->rbuf))
1061 con->st &= ~DONE_CWD;
1063 con->st |= DONE_CWD;
1067 case HOSTERR: case CONREFUSED: case FWRITEERR: case FOPENERR:
1068 case FTPNSFOD: case FTPLOGINC: case FTPNOPASV:
1069 /* Fatal errors, give up. */
1072 case CONSOCKERR: case CONERROR: case FTPSRVERR: case FTPRERR:
1073 case WRITEFAILED: case FTPUNKNOWNTYPE: case CONPORTERR:
1074 case BINDERR: case LISTENERR: case ACCEPTERR:
1075 case FTPPORTERR: case FTPLOGREFUSED: case FTPINVPASV:
1076 printwhat (count, opt.ntry);
1077 /* non-fatal errors */
1081 /* If the control connection was closed, the retrieval
1082 will be considered OK if f->size == len. */
1083 if (!f || len != f->size)
1085 printwhat (count, opt.ntry);
1097 /* If we get out of the switch above without continue'ing, we've
1098 successfully downloaded a file. Remember this fact. */
1099 downloaded_file(FILE_DOWNLOADED_NORMALLY, locf);
1101 if (con->st & ON_YOUR_OWN)
1103 CLOSE (RBUF_FD (&con->rbuf));
1104 rbuf_uninitialize (&con->rbuf);
1106 logprintf (LOG_VERBOSE, _("%s (%s) - `%s' saved [%ld]\n\n"),
1107 tms, tmrate, locf, len);
1108 if (!opt.verbose && !opt.quiet)
1110 /* Need to hide the password from the URL. The `if' is here
1111 so that we don't do the needless allocation every
1113 char *hurl = str_url (u->proxy ? u->proxy : u, 1);
1114 logprintf (LOG_NONVERBOSE, "%s URL: %s [%ld] -> \"%s\" [%d]\n",
1115 tms, hurl, len, locf, count);
1119 if ((con->cmd & DO_LIST))
1120 /* This is a directory listing file. */
1122 if (!opt.remove_listing)
1123 /* --dont-remove-listing was specified, so do count this towards the
1124 number of bytes and files downloaded. */
1126 downloaded_increase (len);
1130 /* Deletion of listing files is not controlled by --delete-after, but
1131 by the more specific option --dont-remove-listing, and the code
1132 to do this deletion is in another function. */
1135 /* This is not a directory listing file. */
1137 /* Unlike directory listing files, don't pretend normal files weren't
1138 downloaded if they're going to be deleted. People seeding proxies,
1139 for instance, may want to know how many bytes and files they've
1140 downloaded through it. */
1141 downloaded_increase (len);
1144 if (opt.delete_after)
1146 DEBUGP (("Removing file due to --delete-after in"
1147 " ftp_loop_internal():\n"));
1148 logprintf (LOG_VERBOSE, _("Removing %s.\n"), locf);
1150 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1154 /* Restore the original leave-pendingness. */
1156 con->cmd |= LEAVE_PENDING;
1158 con->cmd &= ~LEAVE_PENDING;
1160 } while (!opt.ntry || (count < opt.ntry));
1162 if (rbuf_initialized_p (&con->rbuf) && (con->st & ON_YOUR_OWN))
1164 CLOSE (RBUF_FD (&con->rbuf));
1165 rbuf_uninitialize (&con->rbuf);
1170 /* Return the directory listing in a reusable format. The directory
1171 is specifed in u->dir. */
1172 static struct fileinfo *
1173 ftp_get_listing (struct urlinfo *u, ccon *con)
1177 char *olocal = u->local;
1178 char *list_filename, *ofile;
1180 con->st &= ~ON_YOUR_OWN;
1181 con->cmd |= (DO_LIST | LEAVE_PENDING);
1182 con->cmd &= ~DO_RETR;
1183 /* Get the listing filename. */
1185 u->file = LIST_FILENAME;
1186 list_filename = url_filename (u);
1188 u->local = list_filename;
1189 DEBUGP ((_("Using `%s' as listing tmp file.\n"), list_filename));
1190 err = ftp_loop_internal (u, NULL, con);
1193 f = ftp_parse_ls (list_filename, host_type);
1196 if (opt.remove_listing)
1198 if (unlink (list_filename))
1199 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1201 logprintf (LOG_VERBOSE, _("Removed `%s'.\n"), list_filename);
1203 xfree (list_filename);
1204 con->cmd &= ~DO_LIST;
1208 static uerr_t ftp_retrieve_dirs PARAMS ((struct urlinfo *, struct fileinfo *,
1210 static uerr_t ftp_retrieve_glob PARAMS ((struct urlinfo *, ccon *, int));
1211 static struct fileinfo *delelement PARAMS ((struct fileinfo *,
1212 struct fileinfo **));
1213 static void freefileinfo PARAMS ((struct fileinfo *f));
1215 /* Retrieve a list of files given in struct fileinfo linked list. If
1216 a file is a symbolic link, do not retrieve it, but rather try to
1217 set up a similar link on the local disk, if the symlinks are
1220 If opt.recursive is set, after all files have been retrieved,
1221 ftp_retrieve_dirs will be called to retrieve the directories. */
1223 ftp_retrieve_list (struct urlinfo *u, struct fileinfo *f, ccon *con)
1225 static int depth = 0;
1227 char *olocal, *ofile;
1228 struct fileinfo *orig;
1233 /* Increase the depth. */
1235 if (opt.reclevel != INFINITE_RECURSION && depth > opt.reclevel)
1237 DEBUGP ((_("Recursion depth %d exceeded max. depth %d.\n"),
1238 depth, opt.reclevel));
1246 con->st &= ~ON_YOUR_OWN;
1247 if (!(con->st & DONE_CWD))
1250 con->cmd &= ~DO_CWD;
1251 con->cmd |= (DO_RETR | LEAVE_PENDING);
1253 if (!rbuf_initialized_p (&con->rbuf))
1254 con->cmd |= DO_LOGIN;
1256 con->cmd &= ~DO_LOGIN;
1258 err = RETROK; /* in case it's not used */
1262 if (downloaded_exceeds_quota ())
1270 u->local = url_filename (u);
1274 if (opt.timestamping && f->type == FT_PLAINFILE)
1277 /* If conversion of HTML files retrieved via FTP is ever implemented,
1278 we'll need to stat() <file>.orig here when -K has been specified.
1279 I'm not implementing it now since files on an FTP server are much
1280 more likely than files on an HTTP server to legitimately have a
1282 if (!stat (u->local, &st))
1284 /* Else, get it from the file. */
1285 local_size = st.st_size;
1287 if (local_size == f->size && tml >= f->tstamp)
1289 logprintf (LOG_VERBOSE, _("\
1290 Server file no newer than local file `%s' -- not retrieving.\n\n"), u->local);
1293 else if (local_size != f->size)
1295 if (host_type == ST_VMS)
1297 logprintf (LOG_VERBOSE, _("\
1298 Cannot compare sizes, remote system is VMS.\n"));
1303 logprintf (LOG_VERBOSE, _("\
1304 The sizes do not match (local %ld) -- retrieving.\n"), local_size);
1308 } /* opt.timestamping && f->type == FT_PLAINFILE */
1312 /* If opt.retr_symlinks is defined, we treat symlinks as
1313 if they were normal files. There is currently no way
1314 to distinguish whether they might be directories, and
1316 if (!opt.retr_symlinks)
1320 logputs (LOG_NOTQUIET,
1321 _("Invalid name of the symlink, skipping.\n"));
1325 /* Check whether we already have the correct
1327 int rc = lstat (u->local, &st);
1330 size_t len = strlen (f->linkto) + 1;
1331 if (S_ISLNK (st.st_mode))
1333 char *link_target = (char *)alloca (len);
1334 size_t n = readlink (u->local, link_target, len);
1336 && (memcmp (link_target, f->linkto, n) == 0))
1338 logprintf (LOG_VERBOSE, _("\
1339 Already have correct symlink %s -> %s\n\n"),
1340 u->local, f->linkto);
1346 logprintf (LOG_VERBOSE, _("Creating symlink %s -> %s\n"),
1347 u->local, f->linkto);
1348 /* Unlink before creating symlink! */
1350 if (symlink (f->linkto, u->local) == -1)
1351 logprintf (LOG_NOTQUIET, "symlink: %s\n",
1353 logputs (LOG_VERBOSE, "\n");
1354 } /* have f->linkto */
1355 #else /* not HAVE_SYMLINK */
1356 logprintf (LOG_NOTQUIET,
1357 _("Symlinks not supported, skipping symlink `%s'.\n"),
1359 #endif /* not HAVE_SYMLINK */
1361 else /* opt.retr_symlinks */
1364 err = ftp_loop_internal (u, f, con);
1365 } /* opt.retr_symlinks */
1369 logprintf (LOG_NOTQUIET, _("Skipping directory `%s'.\n"),
1373 /* Call the retrieve loop. */
1375 err = ftp_loop_internal (u, f, con);
1378 logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
1383 /* Set the time-stamp information to the local file. Symlinks
1384 are not to be stamped because it sets the stamp on the
1387 && !(f->type == FT_SYMLINK && !opt.retr_symlinks)
1390 && file_exists_p (u->local))
1392 touch (u->local, f->tstamp);
1394 else if (f->tstamp == -1)
1395 logprintf (LOG_NOTQUIET, _("%s: corrupt time-stamp.\n"), u->local);
1397 if (f->perms && f->type == FT_PLAINFILE && dlthis)
1398 chmod (u->local, f->perms);
1400 DEBUGP (("Unrecognized permissions for %s.\n", u->local));
1405 /* Break on fatals. */
1406 if (err == QUOTEXC || err == HOSTERR || err == FWRITEERR)
1408 con->cmd &= ~ (DO_CWD | DO_LOGIN);
1411 /* We do not want to call ftp_retrieve_dirs here */
1412 if (opt.recursive &&
1413 !(opt.reclevel != INFINITE_RECURSION && depth >= opt.reclevel))
1414 err = ftp_retrieve_dirs (u, orig, con);
1415 else if (opt.recursive)
1416 DEBUGP ((_("Will not retrieve dirs since depth is %d (max %d).\n"),
1417 depth, opt.reclevel));
1422 /* Retrieve the directories given in a file list. This function works
1423 by simply going through the linked list and calling
1424 ftp_retrieve_glob on each directory entry. The function knows
1425 about excluded directories. */
1427 ftp_retrieve_dirs (struct urlinfo *u, struct fileinfo *f, ccon *con)
1430 char *current_container = NULL;
1431 int current_length = 0;
1433 for (; f; f = f->next)
1437 if (downloaded_exceeds_quota ())
1439 if (f->type != FT_DIRECTORY)
1442 len = 1 + strlen (u->dir) + 1 + strlen (f->name) + 1;
1443 /* Allocate u->dir off stack, but reallocate only if a larger
1444 string is needed. */
1445 if (len > current_length)
1446 current_container = (char *)alloca (len);
1447 u->dir = current_container;
1448 /* When retrieving recursively, all directories must be
1449 absolute. This restriction will (hopefully!) be lifted in
1451 sprintf (u->dir, "/%s%s%s", odir + (*odir == '/'),
1452 (!*odir || (*odir == '/' && !* (odir + 1))) ? "" : "/", f->name);
1453 if (!accdir (u->dir, ALLABS))
1455 logprintf (LOG_VERBOSE, _("\
1456 Not descending to `%s' as it is excluded/not-included.\n"), u->dir);
1460 con->st &= ~DONE_CWD;
1461 ftp_retrieve_glob (u, con, GETALL);
1462 /* Set the time-stamp? */
1465 if (opt.quota && opt.downloaded > opt.quota)
1472 /* A near-top-level function to retrieve the files in a directory.
1473 The function calls ftp_get_listing, to get a linked list of files.
1474 Then it weeds out the file names that do not match the pattern.
1475 ftp_retrieve_list is called with this updated list as an argument.
1477 If the argument ACTION is GETONE, just download the file (but first
1478 get the listing, so that the time-stamp is heeded); if it's GLOBALL,
1479 use globbing; if it's GETALL, download the whole directory. */
1481 ftp_retrieve_glob (struct urlinfo *u, ccon *con, int action)
1483 struct fileinfo *orig, *start;
1486 con->cmd |= LEAVE_PENDING;
1488 orig = ftp_get_listing (u, con);
1490 /* First: weed out that do not conform the global rules given in
1491 opt.accepts and opt.rejects. */
1492 if (opt.accepts || opt.rejects)
1494 struct fileinfo *f = orig;
1498 if (f->type != FT_DIRECTORY && !acceptable (f->name))
1500 logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"), f->name);
1501 f = delelement (f, &start);
1507 /* Now weed out the files that do not match our globbing pattern.
1508 If we are dealing with a globbing pattern, that is. */
1509 if (*u->file && (action == GLOBALL || action == GETONE))
1512 struct fileinfo *f = start;
1516 matchres = fnmatch (u->file, f->name, 0);
1519 logprintf (LOG_NOTQUIET, "%s: %s\n", u->local,
1523 if (matchres == FNM_NOMATCH)
1524 f = delelement (f, &start); /* delete the element from the list */
1526 f = f->next; /* leave the element in the list */
1530 freefileinfo (start);
1531 return RETRBADPATTERN;
1537 /* Just get everything. */
1538 ftp_retrieve_list (u, start, con);
1542 if (action == GLOBALL)
1545 /* #### This message SUCKS. We should see what was the
1546 reason that nothing was retrieved. */
1547 logprintf (LOG_VERBOSE, _("No matches on pattern `%s'.\n"), u->file);
1549 else /* GETONE or GETALL */
1551 /* Let's try retrieving it anyway. */
1552 con->st |= ON_YOUR_OWN;
1553 res = ftp_loop_internal (u, NULL, con);
1557 freefileinfo (start);
1558 if (downloaded_exceeds_quota ())
1561 /* #### Should we return `res' here? */
1565 /* The wrapper that calls an appropriate routine according to contents
1566 of URL. Inherently, its capabilities are limited on what can be
1567 encoded into a URL. */
1569 ftp_loop (struct urlinfo *u, int *dt)
1571 ccon con; /* FTP connection */
1576 rbuf_uninitialize (&con.rbuf);
1577 con.st = ON_YOUR_OWN;
1578 res = RETROK; /* in case it's not used */
1580 /* If the file name is empty, the user probably wants a directory
1581 index. We'll provide one, properly HTML-ized. Unless
1582 opt.htmlify is 0, of course. :-) */
1583 if (!*u->file && !opt.recursive)
1585 struct fileinfo *f = ftp_get_listing (u, &con);
1591 char *filename = (opt.output_document
1592 ? xstrdup (opt.output_document)
1593 : (u->local ? xstrdup (u->local)
1594 : url_filename (u)));
1595 res = ftp_index (filename, u, f);
1596 if (res == FTPOK && opt.verbose)
1598 if (!opt.output_document)
1602 if (stat (filename, &st) == 0)
1606 logprintf (LOG_NOTQUIET,
1607 _("Wrote HTML-ized index to `%s' [%ld].\n"),
1611 logprintf (LOG_NOTQUIET,
1612 _("Wrote HTML-ized index to `%s'.\n"),
1622 int wild = has_wildcards_p (u->file);
1623 if ((opt.ftp_glob && wild) || opt.recursive || opt.timestamping)
1625 /* ftp_retrieve_glob is a catch-all function that gets called
1626 if we need globbing, time-stamping or recursion. Its
1627 third argument is just what we really need. */
1628 ftp_retrieve_glob (u, &con,
1629 (opt.ftp_glob && wild) ? GLOBALL : GETONE);
1632 res = ftp_loop_internal (u, NULL, &con);
1638 /* If a connection was left, quench it. */
1639 if (rbuf_initialized_p (&con.rbuf))
1640 CLOSE (RBUF_FD (&con.rbuf));
1646 /* Delete an element from the fileinfo linked list. Returns the
1647 address of the next element, or NULL if the list is exhausted. It
1648 can modify the start of the list. */
1649 static struct fileinfo *
1650 delelement (struct fileinfo *f, struct fileinfo **start)
1652 struct fileinfo *prev = f->prev;
1653 struct fileinfo *next = f->next;
1656 FREE_MAYBE (f->linkto);
1668 /* Free the fileinfo linked list of files. */
1670 freefileinfo (struct fileinfo *f)
1674 struct fileinfo *next = f->next;