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>
37 # include <netdb.h> /* for h_errno */
60 /* File where the "ls -al" listing will be saved. */
61 #define LIST_FILENAME ".listing"
63 extern char ftp_last_respline[];
65 /* Look for regexp "( *[0-9]+ *byte" (literal parenthesis) anywhere in
66 the string S, and return the number converted to long, if found, 0
69 ftp_expected_bytes (const char *s)
75 while (*s && *s != '(')
79 for (++s; *s && ISSPACE (*s); s++);
87 res = (*s - '0') + 10 * res;
90 while (*s && ISDIGIT (*s));
93 while (*s && ISSPACE (*s))
97 if (TOLOWER (*s) != 'b')
99 if (strncasecmp (s, "byte", 4))
107 /* Retrieves a file with denoted parameters through opening an FTP
108 connection to the server. It always closes the data connection,
109 and closes the control connection in case of error. */
111 getftp (struct urlinfo *u, long *len, long restval, ccon *con)
113 int csock, dtsock, res;
116 char *user, *passwd, *respline;
118 unsigned char pasv_addr[6];
120 int passive_mode_open = 0;
121 long expected_bytes = 0L;
123 assert (con != NULL);
124 assert (u->local != NULL);
125 /* Debug-check of the sanity of the request by making sure that LIST
126 and RETR are never both requested (since we can handle only one
128 assert (!((cmd & DO_LIST) && (cmd & DO_RETR)));
129 /* Make sure that at least *something* is requested. */
130 assert ((cmd & (DO_LIST | DO_CWD | DO_RETR | DO_LOGIN)) != 0);
134 search_netrc (u->host, (const char **)&user, (const char **)&passwd, 1);
135 user = user ? user : opt.ftp_acc;
137 opt.ftp_pass = ftp_getaddress ();
138 passwd = passwd ? passwd : opt.ftp_pass;
139 assert (user && passwd);
144 if (!(cmd & DO_LOGIN))
145 csock = RBUF_FD (&con->rbuf);
146 else /* cmd & DO_LOGIN */
148 /* Login to the server: */
150 /* First: Establish the control connection. */
151 logprintf (LOG_VERBOSE, _("Connecting to %s:%hu... "), u->host, u->port);
152 err = make_connection (&csock, u->host, u->port);
153 if (cmd & LEAVE_PENDING)
154 rbuf_initialize (&con->rbuf, csock);
156 rbuf_uninitialize (&con->rbuf);
159 /* Do not close the socket in first several cases, since it
160 wasn't created at all. */
162 logputs (LOG_VERBOSE, "\n");
163 logprintf (LOG_NOTQUIET, "%s: %s\n", u->host, herrmsg (h_errno));
167 logputs (LOG_VERBOSE, "\n");
168 logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
172 logputs (LOG_VERBOSE, "\n");
173 logprintf (LOG_NOTQUIET, _("Connection to %s:%hu refused.\n"),
176 rbuf_uninitialize (&con->rbuf);
179 logputs (LOG_VERBOSE, "\n");
180 logprintf (LOG_NOTQUIET, "connect: %s\n", strerror (errno));
182 rbuf_uninitialize (&con->rbuf);
189 /* Since this is a new connection, we may safely discard
190 anything left in the buffer. */
191 rbuf_discard (&con->rbuf);
193 /* Second: Login with proper USER/PASS sequence. */
194 logputs (LOG_VERBOSE, _("connected!\n"));
195 logprintf (LOG_VERBOSE, _("Logging in as %s ... "), user);
196 if (opt.server_response)
197 logputs (LOG_ALWAYS, "\n");
198 err = ftp_login (&con->rbuf, user, passwd);
199 /* FTPRERR, FTPSRVERR, WRITEFAILED, FTPLOGREFUSED, FTPLOGINC */
203 logputs (LOG_VERBOSE, "\n");
204 logputs (LOG_NOTQUIET, _("\
205 Error in server response, closing control connection.\n"));
207 rbuf_uninitialize (&con->rbuf);
211 logputs (LOG_VERBOSE, "\n");
212 logputs (LOG_NOTQUIET, _("Error in server greeting.\n"));
214 rbuf_uninitialize (&con->rbuf);
218 logputs (LOG_VERBOSE, "\n");
219 logputs (LOG_NOTQUIET,
220 _("Write failed, closing control connection.\n"));
222 rbuf_uninitialize (&con->rbuf);
226 logputs (LOG_VERBOSE, "\n");
227 logputs (LOG_NOTQUIET, _("The server refuses login.\n"));
229 rbuf_uninitialize (&con->rbuf);
230 return FTPLOGREFUSED;
233 logputs (LOG_VERBOSE, "\n");
234 logputs (LOG_NOTQUIET, _("Login incorrect.\n"));
236 rbuf_uninitialize (&con->rbuf);
240 if (!opt.server_response)
241 logputs (LOG_VERBOSE, _("Logged in!\n"));
248 /* Third: Get the system type */
249 if (!opt.server_response)
250 logprintf (LOG_VERBOSE, "==> SYST ... ");
251 err = ftp_syst (&con->rbuf, &con->rs);
256 logputs (LOG_VERBOSE, "\n");
257 logputs (LOG_NOTQUIET, _("\
258 Error in server response, closing control connection.\n"));
260 rbuf_uninitialize (&con->rbuf);
264 logputs (LOG_VERBOSE, "\n");
265 logputs (LOG_NOTQUIET,
266 _("Server error, can't determine system type.\n"));
269 /* Everything is OK. */
275 if (!opt.server_response)
276 logputs (LOG_VERBOSE, _("done. "));
278 /* Fourth: Find the initial ftp directory */
280 if (!opt.server_response)
281 logprintf (LOG_VERBOSE, "==> PWD ... ");
282 err = ftp_pwd(&con->rbuf, &con->id);
286 case FTPRERR || FTPSRVERR :
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 logputs (LOG_VERBOSE, _("\nREST failed, starting from scratch.\n"));
653 if (err != FTPRESTFAIL && !opt.server_response)
654 logputs (LOG_VERBOSE, _("done. "));
655 } /* restval && cmd & DO_RETR */
661 if (!opt.server_response)
664 logputs (LOG_VERBOSE, "\n");
665 logprintf (LOG_VERBOSE, "==> RETR %s ... ", u->file);
668 err = ftp_retr (&con->rbuf, u->file);
669 /* FTPRERR, WRITEFAILED, FTPNSFOD */
673 logputs (LOG_VERBOSE, "\n");
674 logputs (LOG_NOTQUIET, _("\
675 Error in server response, closing control connection.\n"));
678 rbuf_uninitialize (&con->rbuf);
682 logputs (LOG_VERBOSE, "\n");
683 logputs (LOG_NOTQUIET,
684 _("Write failed, closing control connection.\n"));
687 rbuf_uninitialize (&con->rbuf);
691 logputs (LOG_VERBOSE, "\n");
692 logprintf (LOG_NOTQUIET, _("No such file `%s'.\n\n"), u->file);
704 if (!opt.server_response)
705 logputs (LOG_VERBOSE, _("done.\n"));
706 expected_bytes = ftp_expected_bytes (ftp_last_respline);
711 if (!opt.server_response)
712 logputs (LOG_VERBOSE, "==> LIST ... ");
713 /* As Maciej W. Rozycki (macro@ds2.pg.gda.pl) says, `LIST'
714 without arguments is better than `LIST .'; confirmed by
716 err = ftp_list (&con->rbuf, NULL);
717 /* FTPRERR, WRITEFAILED */
721 logputs (LOG_VERBOSE, "\n");
722 logputs (LOG_NOTQUIET, _("\
723 Error in server response, closing control connection.\n"));
726 rbuf_uninitialize (&con->rbuf);
730 logputs (LOG_VERBOSE, "\n");
731 logputs (LOG_NOTQUIET,
732 _("Write failed, closing control connection.\n"));
735 rbuf_uninitialize (&con->rbuf);
739 logputs (LOG_VERBOSE, "\n");
740 logprintf (LOG_NOTQUIET, _("No such file or directory `%s'.\n\n"),
752 if (!opt.server_response)
753 logputs (LOG_VERBOSE, _("done.\n"));
754 expected_bytes = ftp_expected_bytes (ftp_last_respline);
755 } /* cmd & DO_LIST */
757 /* Some FTP servers return the total length of file after REST
758 command, others just return the remaining size. */
759 if (*len && restval && expected_bytes
760 && (expected_bytes == *len - restval))
762 DEBUGP (("Lying FTP server found, adjusting.\n"));
763 expected_bytes = *len;
766 /* If no transmission was required, then everything is OK. */
767 if (!(cmd & (DO_LIST | DO_RETR)))
770 if (!passive_mode_open) /* we are not using pasive mode so we need
773 /* Open the data transmission socket by calling acceptport(). */
774 err = acceptport (&dtsock);
775 /* Possible errors: ACCEPTERR. */
776 if (err == ACCEPTERR)
778 logprintf (LOG_NOTQUIET, "accept: %s\n", strerror (errno));
783 /* Open the file -- if opt.dfp is set, use it instead. */
784 if (!opt.dfp || con->cmd & DO_LIST)
786 mkalldirs (u->local);
788 rotate_backups (u->local);
789 /* #### Is this correct? */
790 chmod (u->local, 0600);
792 fp = fopen (u->local, restval ? "ab" : "wb");
795 logprintf (LOG_NOTQUIET, "%s: %s\n", u->local, strerror (errno));
797 rbuf_uninitialize (&con->rbuf);
807 /* This will silently fail for streams that don't correspond
808 to regular files, but that's OK. */
816 logprintf (LOG_VERBOSE, _("Length: %s"), legible (*len));
818 logprintf (LOG_VERBOSE, _(" [%s to go]"), legible (*len - restval));
819 logputs (LOG_VERBOSE, "\n");
821 else if (expected_bytes)
823 logprintf (LOG_VERBOSE, _("Length: %s"), legible (expected_bytes));
825 logprintf (LOG_VERBOSE, _(" [%s to go]"),
826 legible (expected_bytes - restval));
827 logputs (LOG_VERBOSE, _(" (unauthoritative)\n"));
830 /* Get the contents of the document. */
831 res = get_contents (dtsock, fp, len, restval, expected_bytes, &con->rbuf, 0);
832 con->dltime = elapsed_time ();
833 tms = time_str (NULL);
834 tmrate = rate (*len - restval, con->dltime, 0);
835 /* Close data connection socket. */
837 /* Close the local file. */
839 /* Close or flush the file. We have to be careful to check for
840 error here. Checking the result of fwrite() is not enough --
841 errors could go unnoticed! */
843 if (!opt.dfp || con->cmd & DO_LIST)
844 flush_res = fclose (fp);
846 flush_res = fflush (fp);
847 if (flush_res == EOF)
850 /* If get_contents couldn't write to fp, bail out. */
853 logprintf (LOG_NOTQUIET, _("%s: %s, closing control connection.\n"),
854 u->local, strerror (errno));
856 rbuf_uninitialize (&con->rbuf);
861 logprintf (LOG_NOTQUIET, _("%s (%s) - Data connection: %s; "),
862 tms, tmrate, strerror (errno));
863 if (opt.server_response)
864 logputs (LOG_ALWAYS, "\n");
867 /* Get the server to tell us if everything is retrieved. */
868 err = ftp_response (&con->rbuf, &respline);
869 /* ...and empty the buffer. */
870 rbuf_discard (&con->rbuf);
874 /* The control connection is decidedly closed. Print the time
875 only if it hasn't already been printed. */
877 logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
878 logputs (LOG_NOTQUIET, _("Control connection closed.\n"));
879 /* If there is an error on the control connection, close it, but
880 return FTPRETRINT, since there is a possibility that the
881 whole file was retrieved nevertheless (but that is for
882 ftp_loop_internal to decide). */
884 rbuf_uninitialize (&con->rbuf);
887 /* If retrieval failed for any reason, return FTPRETRINT, but do not
888 close socket, since the control connection is still alive. If
889 there is something wrong with the control connection, it will
890 become apparent later. */
891 if (*respline != '2')
895 logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
896 logputs (LOG_NOTQUIET, _("Data transfer aborted.\n"));
903 /* What now? The data connection was erroneous, whereas the
904 response says everything is OK. We shall play it safe. */
908 if (!(cmd & LEAVE_PENDING))
910 /* I should probably send 'QUIT' and check for a reply, but this
911 is faster. #### Is it OK, though? */
913 rbuf_uninitialize (&con->rbuf);
915 /* If it was a listing, and opt.server_response is true,
917 if (opt.server_response && (con->cmd & DO_LIST))
919 mkalldirs (u->local);
920 fp = fopen (u->local, "r");
922 logprintf (LOG_ALWAYS, "%s: %s\n", u->local, strerror (errno));
926 /* The lines are being read with read_whole_line because of
927 no-buffering on opt.lfile. */
928 while ((line = read_whole_line (fp)))
930 logprintf (LOG_ALWAYS, "%s\n", line);
935 } /* con->cmd & DO_LIST && server_response */
940 /* A one-file FTP loop. This is the part where FTP retrieval is
941 retried, and retried, and retried, and...
943 This loop either gets commands from con, or (if ON_YOUR_OWN is
944 set), makes them up to retrieve the file given by the URL. */
946 ftp_loop_internal (struct urlinfo *u, struct fileinfo *f, ccon *con)
950 char *tms, *tmrate, *locf;
955 u->local = url_filename (u);
957 if (opt.noclobber && file_exists_p (u->local))
959 logprintf (LOG_VERBOSE,
960 _("File `%s' already there, not retrieving.\n"), u->local);
961 /* If the file is there, we suppose it's retrieved OK. */
965 /* Remove it if it's a link. */
966 remove_link (u->local);
967 if (!opt.output_document)
970 locf = opt.output_document;
974 if (con->st & ON_YOUR_OWN)
975 con->st = ON_YOUR_OWN;
977 orig_lp = con->cmd & LEAVE_PENDING ? 1 : 0;
982 /* Increment the pass counter. */
984 sleep_between_retrievals (count);
985 if (con->st & ON_YOUR_OWN)
988 con->cmd |= (DO_RETR | LEAVE_PENDING);
989 if (rbuf_initialized_p (&con->rbuf))
990 con->cmd &= ~ (DO_LOGIN | DO_CWD);
992 con->cmd |= (DO_LOGIN | DO_CWD);
994 else /* not on your own */
996 if (rbuf_initialized_p (&con->rbuf))
997 con->cmd &= ~DO_LOGIN;
999 con->cmd |= DO_LOGIN;
1000 if (con->st & DONE_CWD)
1001 con->cmd &= ~DO_CWD;
1005 /* Assume no restarting. */
1007 if ((count > 1 || opt.always_rest)
1008 && !(con->cmd & DO_LIST)
1009 && file_exists_p (u->local))
1010 if (stat (u->local, &st) == 0)
1011 restval = st.st_size;
1012 /* Get the current time string. */
1013 tms = time_str (NULL);
1014 /* Print fetch message, if opt.verbose. */
1017 char *hurl = str_url (u->proxy ? u->proxy : u, 1);
1021 sprintf (tmp, _("(try:%2d)"), count);
1022 logprintf (LOG_VERBOSE, "--%s-- %s\n %s => `%s'\n",
1023 tms, hurl, tmp, locf);
1025 ws_changetitle (hurl, 1);
1029 /* Send getftp the proper length, if fileinfo was provided. */
1034 err = getftp (u, &len, restval, con);
1036 tms = time_str (NULL);
1037 tmrate = rate (len - restval, con->dltime, 0);
1039 if (!rbuf_initialized_p (&con->rbuf))
1040 con->st &= ~DONE_CWD;
1042 con->st |= DONE_CWD;
1046 case HOSTERR: case CONREFUSED: case FWRITEERR: case FOPENERR:
1047 case FTPNSFOD: case FTPLOGINC: case FTPNOPASV:
1048 /* Fatal errors, give up. */
1051 case CONSOCKERR: case CONERROR: case FTPSRVERR: case FTPRERR:
1052 case WRITEFAILED: case FTPUNKNOWNTYPE: case CONPORTERR:
1053 case BINDERR: case LISTENERR: case ACCEPTERR:
1054 case FTPPORTERR: case FTPLOGREFUSED: case FTPINVPASV:
1055 printwhat (count, opt.ntry);
1056 /* non-fatal errors */
1060 /* If the control connection was closed, the retrieval
1061 will be considered OK if f->size == len. */
1062 if (!f || len != f->size)
1064 printwhat (count, opt.ntry);
1076 /* If we get out of the switch above without continue'ing, we've
1077 successfully downloaded a file. Remember this fact. */
1078 downloaded_file(FILE_DOWNLOADED_NORMALLY, locf);
1080 if (con->st & ON_YOUR_OWN)
1082 CLOSE (RBUF_FD (&con->rbuf));
1083 rbuf_uninitialize (&con->rbuf);
1085 logprintf (LOG_VERBOSE, _("%s (%s) - `%s' saved [%ld]\n\n"),
1086 tms, tmrate, locf, len);
1087 if (!opt.verbose && !opt.quiet)
1089 /* Need to hide the password from the URL. The `if' is here
1090 so that we don't do the needless allocation every
1092 char *hurl = str_url (u->proxy ? u->proxy : u, 1);
1093 logprintf (LOG_NONVERBOSE, "%s URL: %s [%ld] -> \"%s\" [%d]\n",
1094 tms, hurl, len, locf, count);
1098 if ((con->cmd & DO_LIST))
1099 /* This is a directory listing file. */
1101 if (!opt.remove_listing)
1102 /* --dont-remove-listing was specified, so do count this towards the
1103 number of bytes and files downloaded. */
1105 downloaded_increase (len);
1109 /* Deletion of listing files is not controlled by --delete-after, but
1110 by the more specific option --dont-remove-listing, and the code
1111 to do this deletion is in another function. */
1114 /* This is not a directory listing file. */
1116 /* Unlike directory listing files, don't pretend normal files weren't
1117 downloaded if they're going to be deleted. People seeding proxies,
1118 for instance, may want to know how many bytes and files they've
1119 downloaded through it. */
1120 downloaded_increase (len);
1123 if (opt.delete_after)
1125 DEBUGP (("Removing file due to --delete-after in"
1126 " ftp_loop_internal():\n"));
1127 logprintf (LOG_VERBOSE, _("Removing %s.\n"), locf);
1129 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1133 /* Restore the original leave-pendingness. */
1135 con->cmd |= LEAVE_PENDING;
1137 con->cmd &= ~LEAVE_PENDING;
1139 } while (!opt.ntry || (count < opt.ntry));
1141 if (rbuf_initialized_p (&con->rbuf) && (con->st & ON_YOUR_OWN))
1143 CLOSE (RBUF_FD (&con->rbuf));
1144 rbuf_uninitialize (&con->rbuf);
1149 /* Return the directory listing in a reusable format. The directory
1150 is specifed in u->dir. */
1151 static struct fileinfo *
1152 ftp_get_listing (struct urlinfo *u, ccon *con)
1156 char *olocal = u->local;
1157 char *list_filename, *ofile;
1159 con->st &= ~ON_YOUR_OWN;
1160 con->cmd |= (DO_LIST | LEAVE_PENDING);
1161 con->cmd &= ~DO_RETR;
1162 /* Get the listing filename. */
1164 u->file = LIST_FILENAME;
1165 list_filename = url_filename (u);
1167 u->local = list_filename;
1168 DEBUGP ((_("Using `%s' as listing tmp file.\n"), list_filename));
1169 err = ftp_loop_internal (u, NULL, con);
1172 f = ftp_parse_ls (list_filename, con->rs);
1175 if (opt.remove_listing)
1177 if (unlink (list_filename))
1178 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1180 logprintf (LOG_VERBOSE, _("Removed `%s'.\n"), list_filename);
1182 xfree (list_filename);
1183 con->cmd &= ~DO_LIST;
1187 static uerr_t ftp_retrieve_dirs PARAMS ((struct urlinfo *, struct fileinfo *,
1189 static uerr_t ftp_retrieve_glob PARAMS ((struct urlinfo *, ccon *, int));
1190 static struct fileinfo *delelement PARAMS ((struct fileinfo *,
1191 struct fileinfo **));
1192 static void freefileinfo PARAMS ((struct fileinfo *f));
1194 /* Retrieve a list of files given in struct fileinfo linked list. If
1195 a file is a symbolic link, do not retrieve it, but rather try to
1196 set up a similar link on the local disk, if the symlinks are
1199 If opt.recursive is set, after all files have been retrieved,
1200 ftp_retrieve_dirs will be called to retrieve the directories. */
1202 ftp_retrieve_list (struct urlinfo *u, struct fileinfo *f, ccon *con)
1204 static int depth = 0;
1206 char *olocal, *ofile;
1207 struct fileinfo *orig;
1212 /* Increase the depth. */
1214 if (opt.reclevel != INFINITE_RECURSION && depth > opt.reclevel)
1216 DEBUGP ((_("Recursion depth %d exceeded max. depth %d.\n"),
1217 depth, opt.reclevel));
1225 con->st &= ~ON_YOUR_OWN;
1226 if (!(con->st & DONE_CWD))
1229 con->cmd &= ~DO_CWD;
1230 con->cmd |= (DO_RETR | LEAVE_PENDING);
1232 if (!rbuf_initialized_p (&con->rbuf))
1233 con->cmd |= DO_LOGIN;
1235 con->cmd &= ~DO_LOGIN;
1237 err = RETROK; /* in case it's not used */
1241 if (downloaded_exceeds_quota ())
1249 u->local = url_filename (u);
1253 if (opt.timestamping && f->type == FT_PLAINFILE)
1256 /* If conversion of HTML files retrieved via FTP is ever implemented,
1257 we'll need to stat() <file>.orig here when -K has been specified.
1258 I'm not implementing it now since files on an FTP server are much
1259 more likely than files on an HTTP server to legitimately have a
1261 if (!stat (u->local, &st))
1265 /* Else, get it from the file. */
1266 local_size = st.st_size;
1268 /* Compare file sizes only for servers that tell us correct
1269 values. Assumme sizes being equal for servers that lie
1271 cor_val = (con->rs == ST_UNIX || con->rs == ST_WINNT);
1272 eq_size = cor_val ? (local_size == f->size) : 1 ;
1273 if (f->tstamp <= tml && eq_size)
1275 /* Remote file is older, file sizes can be compared and
1277 logprintf (LOG_VERBOSE, _("\
1278 Remote file no newer than local file `%s' -- not retrieving.\n"), u->local);
1283 /* Remote file is newer or sizes cannot be matched */
1284 logprintf (LOG_VERBOSE, _("\
1285 Remote file is newer than local file `%s' -- retrieving.\n\n"),
1290 /* Sizes do not match */
1291 logprintf (LOG_VERBOSE, _("\
1292 The sizes do not match (local %ld) -- retrieving.\n\n"), local_size);
1295 } /* opt.timestamping && f->type == FT_PLAINFILE */
1299 /* If opt.retr_symlinks is defined, we treat symlinks as
1300 if they were normal files. There is currently no way
1301 to distinguish whether they might be directories, and
1303 if (!opt.retr_symlinks)
1307 logputs (LOG_NOTQUIET,
1308 _("Invalid name of the symlink, skipping.\n"));
1312 /* Check whether we already have the correct
1314 int rc = lstat (u->local, &st);
1317 size_t len = strlen (f->linkto) + 1;
1318 if (S_ISLNK (st.st_mode))
1320 char *link_target = (char *)alloca (len);
1321 size_t n = readlink (u->local, link_target, len);
1323 && (memcmp (link_target, f->linkto, n) == 0))
1325 logprintf (LOG_VERBOSE, _("\
1326 Already have correct symlink %s -> %s\n\n"),
1327 u->local, f->linkto);
1333 logprintf (LOG_VERBOSE, _("Creating symlink %s -> %s\n"),
1334 u->local, f->linkto);
1335 /* Unlink before creating symlink! */
1337 if (symlink (f->linkto, u->local) == -1)
1338 logprintf (LOG_NOTQUIET, "symlink: %s\n",
1340 logputs (LOG_VERBOSE, "\n");
1341 } /* have f->linkto */
1342 #else /* not HAVE_SYMLINK */
1343 logprintf (LOG_NOTQUIET,
1344 _("Symlinks not supported, skipping symlink `%s'.\n"),
1346 #endif /* not HAVE_SYMLINK */
1348 else /* opt.retr_symlinks */
1351 err = ftp_loop_internal (u, f, con);
1352 } /* opt.retr_symlinks */
1356 logprintf (LOG_NOTQUIET, _("Skipping directory `%s'.\n"),
1360 /* Call the retrieve loop. */
1362 err = ftp_loop_internal (u, f, con);
1365 logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
1370 /* Set the time-stamp information to the local file. Symlinks
1371 are not to be stamped because it sets the stamp on the
1373 if (!(f->type == FT_SYMLINK && !opt.retr_symlinks)
1376 && file_exists_p (u->local))
1378 /* #### This code repeats in http.c and ftp.c. Move it to a
1380 const char *fl = NULL;
1381 if (opt.output_document)
1383 if (opt.od_known_regular)
1384 fl = opt.output_document;
1389 touch (fl, f->tstamp);
1391 else if (f->tstamp == -1)
1392 logprintf (LOG_NOTQUIET, _("%s: corrupt time-stamp.\n"), u->local);
1394 if (f->perms && f->type == FT_PLAINFILE && dlthis)
1395 chmod (u->local, f->perms);
1397 DEBUGP (("Unrecognized permissions for %s.\n", u->local));
1402 /* Break on fatals. */
1403 if (err == QUOTEXC || err == HOSTERR || err == FWRITEERR)
1405 con->cmd &= ~ (DO_CWD | DO_LOGIN);
1408 /* We do not want to call ftp_retrieve_dirs here */
1409 if (opt.recursive &&
1410 !(opt.reclevel != INFINITE_RECURSION && depth >= opt.reclevel))
1411 err = ftp_retrieve_dirs (u, orig, con);
1412 else if (opt.recursive)
1413 DEBUGP ((_("Will not retrieve dirs since depth is %d (max %d).\n"),
1414 depth, opt.reclevel));
1419 /* Retrieve the directories given in a file list. This function works
1420 by simply going through the linked list and calling
1421 ftp_retrieve_glob on each directory entry. The function knows
1422 about excluded directories. */
1424 ftp_retrieve_dirs (struct urlinfo *u, struct fileinfo *f, ccon *con)
1427 char *current_container = NULL;
1428 int current_length = 0;
1430 for (; f; f = f->next)
1434 if (downloaded_exceeds_quota ())
1436 if (f->type != FT_DIRECTORY)
1439 len = 1 + strlen (u->dir) + 1 + strlen (f->name) + 1;
1440 /* Allocate u->dir off stack, but reallocate only if a larger
1441 string is needed. */
1442 if (len > current_length)
1443 current_container = (char *)alloca (len);
1444 u->dir = current_container;
1445 sprintf (u->dir, "/%s%s%s", odir + (*odir == '/'),
1446 (!*odir || (*odir == '/' && !* (odir + 1))) ? "" : "/", f->name);
1447 if (!accdir (u->dir, ALLABS))
1449 logprintf (LOG_VERBOSE, _("\
1450 Not descending to `%s' as it is excluded/not-included.\n"), u->dir);
1454 con->st &= ~DONE_CWD;
1455 ftp_retrieve_glob (u, con, GETALL);
1456 /* Set the time-stamp? */
1459 if (opt.quota && opt.downloaded > opt.quota)
1466 /* A near-top-level function to retrieve the files in a directory.
1467 The function calls ftp_get_listing, to get a linked list of files.
1468 Then it weeds out the file names that do not match the pattern.
1469 ftp_retrieve_list is called with this updated list as an argument.
1471 If the argument ACTION is GETONE, just download the file (but first
1472 get the listing, so that the time-stamp is heeded); if it's GLOBALL,
1473 use globbing; if it's GETALL, download the whole directory. */
1475 ftp_retrieve_glob (struct urlinfo *u, ccon *con, int action)
1477 struct fileinfo *orig, *start;
1480 con->cmd |= LEAVE_PENDING;
1482 orig = ftp_get_listing (u, con);
1484 /* First: weed out that do not conform the global rules given in
1485 opt.accepts and opt.rejects. */
1486 if (opt.accepts || opt.rejects)
1488 struct fileinfo *f = orig;
1492 if (f->type != FT_DIRECTORY && !acceptable (f->name))
1494 logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"), f->name);
1495 f = delelement (f, &start);
1501 /* Now weed out the files that do not match our globbing pattern.
1502 If we are dealing with a globbing pattern, that is. */
1503 if (*u->file && (action == GLOBALL || action == GETONE))
1506 struct fileinfo *f = start;
1510 matchres = fnmatch (u->file, f->name, 0);
1513 logprintf (LOG_NOTQUIET, "%s: %s\n", u->local,
1517 if (matchres == FNM_NOMATCH)
1518 f = delelement (f, &start); /* delete the element from the list */
1520 f = f->next; /* leave the element in the list */
1524 freefileinfo (start);
1525 return RETRBADPATTERN;
1531 /* Just get everything. */
1532 ftp_retrieve_list (u, start, con);
1536 if (action == GLOBALL)
1539 /* #### This message SUCKS. We should see what was the
1540 reason that nothing was retrieved. */
1541 logprintf (LOG_VERBOSE, _("No matches on pattern `%s'.\n"), u->file);
1543 else /* GETONE or GETALL */
1545 /* Let's try retrieving it anyway. */
1546 con->st |= ON_YOUR_OWN;
1547 res = ftp_loop_internal (u, NULL, con);
1551 freefileinfo (start);
1552 if (downloaded_exceeds_quota ())
1555 /* #### Should we return `res' here? */
1559 /* The wrapper that calls an appropriate routine according to contents
1560 of URL. Inherently, its capabilities are limited on what can be
1561 encoded into a URL. */
1563 ftp_loop (struct urlinfo *u, int *dt)
1565 ccon con; /* FTP connection */
1570 memset (&con, 0, sizeof (con));
1572 rbuf_uninitialize (&con.rbuf);
1573 con.st = ON_YOUR_OWN;
1576 res = RETROK; /* in case it's not used */
1578 /* If the file name is empty, the user probably wants a directory
1579 index. We'll provide one, properly HTML-ized. Unless
1580 opt.htmlify is 0, of course. :-) */
1581 if (!*u->file && !opt.recursive)
1583 struct fileinfo *f = ftp_get_listing (u, &con);
1589 char *filename = (opt.output_document
1590 ? xstrdup (opt.output_document)
1591 : (u->local ? xstrdup (u->local)
1592 : url_filename (u)));
1593 res = ftp_index (filename, u, f);
1594 if (res == FTPOK && opt.verbose)
1596 if (!opt.output_document)
1600 if (stat (filename, &st) == 0)
1604 logprintf (LOG_NOTQUIET,
1605 _("Wrote HTML-ized index to `%s' [%ld].\n"),
1609 logprintf (LOG_NOTQUIET,
1610 _("Wrote HTML-ized index to `%s'.\n"),
1620 int wild = has_wildcards_p (u->file);
1621 if ((opt.ftp_glob && wild) || opt.recursive || opt.timestamping)
1623 /* ftp_retrieve_glob is a catch-all function that gets called
1624 if we need globbing, time-stamping or recursion. Its
1625 third argument is just what we really need. */
1626 ftp_retrieve_glob (u, &con,
1627 (opt.ftp_glob && wild) ? GLOBALL : GETONE);
1630 res = ftp_loop_internal (u, NULL, &con);
1636 /* If a connection was left, quench it. */
1637 if (rbuf_initialized_p (&con.rbuf))
1638 CLOSE (RBUF_FD (&con.rbuf));
1639 FREE_MAYBE (con.id);
1644 /* Delete an element from the fileinfo linked list. Returns the
1645 address of the next element, or NULL if the list is exhausted. It
1646 can modify the start of the list. */
1647 static struct fileinfo *
1648 delelement (struct fileinfo *f, struct fileinfo **start)
1650 struct fileinfo *prev = f->prev;
1651 struct fileinfo *next = f->next;
1654 FREE_MAYBE (f->linkto);
1666 /* Free the fileinfo linked list of files. */
1668 freefileinfo (struct fileinfo *f)
1672 struct fileinfo *next = f->next;