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 */
58 /* File where the "ls -al" listing will be saved. */
59 #define LIST_FILENAME ".listing"
61 extern char ftp_last_respline[];
63 /* #### Global variables?? These two should be members of struct
66 static enum stype host_type=ST_UNIX;
69 /* Look for regexp "( *[0-9]+ *byte" (literal parenthesis) anywhere in
70 the string S, and return the number converted to long, if found, 0
73 ftp_expected_bytes (const char *s)
79 while (*s && *s != '(')
83 for (++s; *s && ISSPACE (*s); s++);
91 res = (*s - '0') + 10 * res;
94 while (*s && ISDIGIT (*s));
97 while (*s && ISSPACE (*s))
101 if (TOLOWER (*s) != 'b')
103 if (strncasecmp (s, "byte", 4))
111 /* Retrieves a file with denoted parameters through opening an FTP
112 connection to the server. It always closes the data connection,
113 and closes the control connection in case of error. */
115 getftp (const struct urlinfo *u, long *len, long restval, ccon *con)
117 int csock, dtsock, res;
120 char *user, *passwd, *respline;
122 unsigned char pasv_addr[6];
124 int passive_mode_open = 0;
125 long expected_bytes = 0L;
127 assert (con != NULL);
128 assert (u->local != NULL);
129 /* Debug-check of the sanity of the request by making sure that LIST
130 and RETR are never both requested (since we can handle only one
132 assert (!((cmd & DO_LIST) && (cmd & DO_RETR)));
133 /* Make sure that at least *something* is requested. */
134 assert ((cmd & (DO_LIST | DO_CWD | DO_RETR | DO_LOGIN)) != 0);
138 search_netrc (u->host, (const char **)&user, (const char **)&passwd, 1);
139 user = user ? user : opt.ftp_acc;
141 opt.ftp_pass = ftp_getaddress ();
142 passwd = passwd ? passwd : opt.ftp_pass;
143 assert (user && passwd);
148 if (!(cmd & DO_LOGIN))
149 csock = RBUF_FD (&con->rbuf);
150 else /* cmd & DO_LOGIN */
152 /* Login to the server: */
154 /* First: Establish the control connection. */
155 logprintf (LOG_VERBOSE, _("Connecting to %s:%hu... "), u->host, u->port);
156 err = make_connection (&csock, u->host, u->port);
157 if (cmd & LEAVE_PENDING)
158 rbuf_initialize (&con->rbuf, csock);
160 rbuf_uninitialize (&con->rbuf);
163 /* Do not close the socket in first several cases, since it
164 wasn't created at all. */
166 logputs (LOG_VERBOSE, "\n");
167 logprintf (LOG_NOTQUIET, "%s: %s\n", u->host, herrmsg (h_errno));
171 logputs (LOG_VERBOSE, "\n");
172 logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
176 logputs (LOG_VERBOSE, "\n");
177 logprintf (LOG_NOTQUIET, _("Connection to %s:%hu refused.\n"),
180 rbuf_uninitialize (&con->rbuf);
183 logputs (LOG_VERBOSE, "\n");
184 logprintf (LOG_NOTQUIET, "connect: %s\n", strerror (errno));
186 rbuf_uninitialize (&con->rbuf);
193 /* Since this is a new connection, we may safely discard
194 anything left in the buffer. */
195 rbuf_discard (&con->rbuf);
197 /* Second: Login with proper USER/PASS sequence. */
198 logputs (LOG_VERBOSE, _("connected!\n"));
199 logprintf (LOG_VERBOSE, _("Logging in as %s ... "), user);
200 if (opt.server_response)
201 logputs (LOG_ALWAYS, "\n");
202 err = ftp_login (&con->rbuf, user, passwd);
203 /* FTPRERR, FTPSRVERR, WRITEFAILED, FTPLOGREFUSED, FTPLOGINC */
207 logputs (LOG_VERBOSE, "\n");
208 logputs (LOG_NOTQUIET, _("\
209 Error in server response, closing control connection.\n"));
211 rbuf_uninitialize (&con->rbuf);
215 logputs (LOG_VERBOSE, "\n");
216 logputs (LOG_NOTQUIET, _("Error in server greeting.\n"));
218 rbuf_uninitialize (&con->rbuf);
222 logputs (LOG_VERBOSE, "\n");
223 logputs (LOG_NOTQUIET,
224 _("Write failed, closing control connection.\n"));
226 rbuf_uninitialize (&con->rbuf);
230 logputs (LOG_VERBOSE, "\n");
231 logputs (LOG_NOTQUIET, _("The server refuses login.\n"));
233 rbuf_uninitialize (&con->rbuf);
234 return FTPLOGREFUSED;
237 logputs (LOG_VERBOSE, "\n");
238 logputs (LOG_NOTQUIET, _("Login incorrect.\n"));
240 rbuf_uninitialize (&con->rbuf);
244 if (!opt.server_response)
245 logputs (LOG_VERBOSE, _("Logged in!\n"));
252 /* Third: Get the system type */
253 if (!opt.server_response)
254 logprintf (LOG_VERBOSE, "==> SYST ... ");
255 err = ftp_syst (&con->rbuf, &host_type);
260 logputs (LOG_VERBOSE, "\n");
261 logputs (LOG_NOTQUIET, _("\
262 Error in server response, closing control connection.\n"));
264 rbuf_uninitialize (&con->rbuf);
268 logputs (LOG_VERBOSE, "\n");
269 logputs (LOG_NOTQUIET,
270 _("Server error, can't determine system type.\n"));
273 /* Everything is OK. */
279 if (!opt.server_response)
280 logputs (LOG_VERBOSE, _("done. "));
282 /* Fourth: Find the initial ftp directory */
284 if (!opt.server_response)
285 logprintf (LOG_VERBOSE, "==> PWD ... ");
286 err = ftp_pwd(&con->rbuf, &pwd);
290 case FTPRERR || FTPSRVERR :
291 logputs (LOG_VERBOSE, "\n");
292 logputs (LOG_NOTQUIET, _("\
293 Error in server response, closing control connection.\n"));
295 rbuf_uninitialize (&con->rbuf);
299 /* Everything is OK. */
305 if (!opt.server_response)
306 logputs (LOG_VERBOSE, _("done.\n"));
308 /* Fifth: Set the FTP type. */
309 if (!opt.server_response)
310 logprintf (LOG_VERBOSE, "==> TYPE %c ... ", TOUPPER (u->ftp_type));
311 err = ftp_type (&con->rbuf, TOUPPER (u->ftp_type));
312 /* FTPRERR, WRITEFAILED, FTPUNKNOWNTYPE */
316 logputs (LOG_VERBOSE, "\n");
317 logputs (LOG_NOTQUIET, _("\
318 Error in server response, closing control connection.\n"));
320 rbuf_uninitialize (&con->rbuf);
324 logputs (LOG_VERBOSE, "\n");
325 logputs (LOG_NOTQUIET,
326 _("Write failed, closing control connection.\n"));
328 rbuf_uninitialize (&con->rbuf);
332 logputs (LOG_VERBOSE, "\n");
333 logprintf (LOG_NOTQUIET,
334 _("Unknown type `%c', closing control connection.\n"),
335 TOUPPER (u->ftp_type));
337 rbuf_uninitialize (&con->rbuf);
340 /* Everything is OK. */
346 if (!opt.server_response)
347 logputs (LOG_VERBOSE, _("done. "));
353 logputs (LOG_VERBOSE, _("==> CWD not needed.\n"));
356 /* Change working directory. If the FTP host runs VMS and
357 the path specified is absolute, we will have to convert
358 it to VMS style as VMS does not like leading slashes */
359 DEBUGP (("changing working directory\n"));
360 if (*(u->dir) == '/')
362 int pwd_len = strlen (pwd);
363 char *result = (char *)alloca (strlen (u->dir) + pwd_len + 10);
369 char *tmp_dir, *tmpp;
370 STRDUP_ALLOCA (tmp_dir, u->dir);
371 for (tmpp = tmp_dir; *tmpp; tmpp++)
374 strcpy (result, pwd);
375 /* pwd ends with ']', we have to get rid of it */
376 result[pwd_len - 1]= '\0';
377 strcat (result, tmp_dir);
378 strcat (result, "]");
383 /* pwd_len == 1 means pwd = "/", but u->dir begins with '/'
386 strcpy (result, pwd);
387 strcat (result, u->dir);
388 /* These look like debugging messages to me. */
390 logprintf (LOG_VERBOSE, "\npwd=\"%s\"", pwd);
391 logprintf (LOG_VERBOSE, "\nu->dir=\"%s\"", u->dir);
398 if (!opt.server_response)
399 logprintf (LOG_VERBOSE, "==> CWD %s ... ", result);
400 err = ftp_cwd (&con->rbuf, result);
404 if (!opt.server_response)
405 logprintf (LOG_VERBOSE, "==> CWD %s ... ", u->dir);
406 err = ftp_cwd (&con->rbuf, u->dir);
408 /* FTPRERR, WRITEFAILED, FTPNSFOD */
412 logputs (LOG_VERBOSE, "\n");
413 logputs (LOG_NOTQUIET, _("\
414 Error in server response, closing control connection.\n"));
416 rbuf_uninitialize (&con->rbuf);
420 logputs (LOG_VERBOSE, "\n");
421 logputs (LOG_NOTQUIET,
422 _("Write failed, closing control connection.\n"));
424 rbuf_uninitialize (&con->rbuf);
428 logputs (LOG_VERBOSE, "\n");
429 logprintf (LOG_NOTQUIET, _("No such directory `%s'.\n\n"),
432 rbuf_uninitialize (&con->rbuf);
442 if (!opt.server_response)
443 logputs (LOG_VERBOSE, _("done.\n"));
446 else /* do not CWD */
447 logputs (LOG_VERBOSE, _("==> CWD not required.\n"));
449 /* If anything is to be retrieved, PORT (or PASV) must be sent. */
450 if (cmd & (DO_LIST | DO_RETR))
452 if (opt.ftp_pasv > 0)
455 unsigned short tport;
457 if (!opt.server_response)
458 logputs (LOG_VERBOSE, "==> PASV ... ");
459 err = ftp_pasv (&con->rbuf, pasv_addr);
460 /* FTPRERR, WRITEFAILED, FTPNOPASV, FTPINVPASV */
464 logputs (LOG_VERBOSE, "\n");
465 logputs (LOG_NOTQUIET, _("\
466 Error in server response, closing control connection.\n"));
468 rbuf_uninitialize (&con->rbuf);
472 logputs (LOG_VERBOSE, "\n");
473 logputs (LOG_NOTQUIET,
474 _("Write failed, closing control connection.\n"));
476 rbuf_uninitialize (&con->rbuf);
480 logputs (LOG_VERBOSE, "\n");
481 logputs (LOG_NOTQUIET, _("Cannot initiate PASV transfer.\n"));
484 logputs (LOG_VERBOSE, "\n");
485 logputs (LOG_NOTQUIET, _("Cannot parse PASV response.\n"));
496 sprintf (thost, "%d.%d.%d.%d",
497 pasv_addr[0], pasv_addr[1], pasv_addr[2], pasv_addr[3]);
498 tport = (pasv_addr[4] << 8) + pasv_addr[5];
499 DEBUGP ((_("Will try connecting to %s:%hu.\n"), thost, tport));
500 err = make_connection (&dtsock, thost, tport);
503 /* Do not close the socket in first several cases,
504 since it wasn't created at all. */
506 logputs (LOG_VERBOSE, "\n");
507 logprintf (LOG_NOTQUIET, "%s: %s\n", thost,
510 rbuf_uninitialize (&con->rbuf);
514 logputs (LOG_VERBOSE, "\n");
515 logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
517 rbuf_uninitialize (&con->rbuf);
521 logputs (LOG_VERBOSE, "\n");
522 logprintf (LOG_NOTQUIET,
523 _("Connection to %s:%hu refused.\n"),
526 rbuf_uninitialize (&con->rbuf);
530 logputs (LOG_VERBOSE, "\n");
531 logprintf (LOG_NOTQUIET, "connect: %s\n",
534 rbuf_uninitialize (&con->rbuf);
542 passive_mode_open= 1; /* Flag to avoid accept port */
543 if (!opt.server_response)
544 logputs (LOG_VERBOSE, _("done. "));
548 if (!passive_mode_open) /* Try to use a port command if PASV failed */
550 if (!opt.server_response)
551 logputs (LOG_VERBOSE, "==> PORT ... ");
552 err = ftp_port (&con->rbuf);
553 /* FTPRERR, WRITEFAILED, bindport (CONSOCKERR, CONPORTERR, BINDERR,
554 LISTENERR), HOSTERR, FTPPORTERR */
558 logputs (LOG_VERBOSE, "\n");
559 logputs (LOG_NOTQUIET, _("\
560 Error in server response, closing control connection.\n"));
563 rbuf_uninitialize (&con->rbuf);
567 logputs (LOG_VERBOSE, "\n");
568 logputs (LOG_NOTQUIET,
569 _("Write failed, closing control connection.\n"));
572 rbuf_uninitialize (&con->rbuf);
576 logputs (LOG_VERBOSE, "\n");
577 logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
580 rbuf_uninitialize (&con->rbuf);
583 case CONPORTERR: case BINDERR: case LISTENERR:
584 /* What now? These problems are local... */
585 logputs (LOG_VERBOSE, "\n");
586 logprintf (LOG_NOTQUIET, _("Bind error (%s).\n"),
592 logputs (LOG_VERBOSE, "\n");
593 logprintf (LOG_NOTQUIET, "%s: %s\n", u->host,
597 rbuf_uninitialize (&con->rbuf);
601 logputs (LOG_VERBOSE, "\n");
602 logputs (LOG_NOTQUIET, _("Invalid PORT.\n"));
605 rbuf_uninitialize (&con->rbuf);
615 if (!opt.server_response)
616 logputs (LOG_VERBOSE, _("done. "));
618 } /* cmd & (DO_LIST | DO_RETR) */
620 /* Restart if needed. */
621 if (restval && (cmd & DO_RETR))
623 if (!opt.server_response)
624 logprintf (LOG_VERBOSE, "==> REST %ld ... ", restval);
625 err = ftp_rest (&con->rbuf, restval);
627 /* FTPRERR, WRITEFAILED, FTPRESTFAIL */
631 logputs (LOG_VERBOSE, "\n");
632 logputs (LOG_NOTQUIET, _("\
633 Error in server response, closing control connection.\n"));
636 rbuf_uninitialize (&con->rbuf);
640 logputs (LOG_VERBOSE, "\n");
641 logputs (LOG_NOTQUIET,
642 _("Write failed, closing control connection.\n"));
645 rbuf_uninitialize (&con->rbuf);
649 logputs (LOG_VERBOSE, _("\nREST failed, starting from scratch.\n"));
659 if (err != FTPRESTFAIL && !opt.server_response)
660 logputs (LOG_VERBOSE, _("done. "));
661 } /* restval && cmd & DO_RETR */
667 if (!opt.server_response)
670 logputs (LOG_VERBOSE, "\n");
671 logprintf (LOG_VERBOSE, "==> RETR %s ... ", u->file);
674 err = ftp_retr (&con->rbuf, u->file);
675 /* FTPRERR, WRITEFAILED, FTPNSFOD */
679 logputs (LOG_VERBOSE, "\n");
680 logputs (LOG_NOTQUIET, _("\
681 Error in server response, closing control connection.\n"));
684 rbuf_uninitialize (&con->rbuf);
688 logputs (LOG_VERBOSE, "\n");
689 logputs (LOG_NOTQUIET,
690 _("Write failed, closing control connection.\n"));
693 rbuf_uninitialize (&con->rbuf);
697 logputs (LOG_VERBOSE, "\n");
698 logprintf (LOG_NOTQUIET, _("No such file `%s'.\n\n"), u->file);
710 if (!opt.server_response)
711 logputs (LOG_VERBOSE, _("done.\n"));
712 expected_bytes = ftp_expected_bytes (ftp_last_respline);
717 if (!opt.server_response)
718 logputs (LOG_VERBOSE, "==> LIST ... ");
719 /* As Maciej W. Rozycki (macro@ds2.pg.gda.pl) says, `LIST'
720 without arguments is better than `LIST .'; confirmed by
722 err = ftp_list (&con->rbuf, NULL);
723 /* FTPRERR, WRITEFAILED */
727 logputs (LOG_VERBOSE, "\n");
728 logputs (LOG_NOTQUIET, _("\
729 Error in server response, closing control connection.\n"));
732 rbuf_uninitialize (&con->rbuf);
736 logputs (LOG_VERBOSE, "\n");
737 logputs (LOG_NOTQUIET,
738 _("Write failed, closing control connection.\n"));
741 rbuf_uninitialize (&con->rbuf);
745 logputs (LOG_VERBOSE, "\n");
746 logprintf (LOG_NOTQUIET, _("No such file or directory `%s'.\n\n"),
758 if (!opt.server_response)
759 logputs (LOG_VERBOSE, _("done.\n"));
760 expected_bytes = ftp_expected_bytes (ftp_last_respline);
761 } /* cmd & DO_LIST */
763 /* Some FTP servers return the total length of file after REST
764 command, others just return the remaining size. */
765 if (*len && restval && expected_bytes
766 && (expected_bytes == *len - restval))
768 DEBUGP (("Lying FTP server found, adjusting.\n"));
769 expected_bytes = *len;
772 /* If no transmission was required, then everything is OK. */
773 if (!(cmd & (DO_LIST | DO_RETR)))
776 if (!passive_mode_open) /* we are not using pasive mode so we need
779 /* Open the data transmission socket by calling acceptport(). */
780 err = acceptport (&dtsock);
781 /* Possible errors: ACCEPTERR. */
782 if (err == ACCEPTERR)
784 logprintf (LOG_NOTQUIET, "accept: %s\n", strerror (errno));
789 /* Open the file -- if opt.dfp is set, use it instead. */
790 if (!opt.dfp || con->cmd & DO_LIST)
792 mkalldirs (u->local);
794 rotate_backups (u->local);
795 /* #### Is this correct? */
796 chmod (u->local, 0600);
798 fp = fopen (u->local, restval ? "ab" : "wb");
801 logprintf (LOG_NOTQUIET, "%s: %s\n", u->local, strerror (errno));
803 rbuf_uninitialize (&con->rbuf);
813 /* This will silently fail for streams that don't correspond
814 to regular files, but that's OK. */
822 logprintf (LOG_VERBOSE, _("Length: %s"), legible (*len));
824 logprintf (LOG_VERBOSE, _(" [%s to go]"), legible (*len - restval));
825 logputs (LOG_VERBOSE, "\n");
827 else if (expected_bytes)
829 logprintf (LOG_VERBOSE, _("Length: %s"), legible (expected_bytes));
831 logprintf (LOG_VERBOSE, _(" [%s to go]"),
832 legible (expected_bytes - restval));
833 logputs (LOG_VERBOSE, _(" (unauthoritative)\n"));
836 /* Get the contents of the document. */
837 res = get_contents (dtsock, fp, len, restval, expected_bytes, &con->rbuf, 0);
838 con->dltime = elapsed_time ();
839 tms = time_str (NULL);
840 tmrate = rate (*len - restval, con->dltime);
841 /* Close data connection socket. */
843 /* Close the local file. */
845 /* Close or flush the file. We have to be careful to check for
846 error here. Checking the result of fwrite() is not enough --
847 errors could go unnoticed! */
849 if (!opt.dfp || con->cmd & DO_LIST)
850 flush_res = fclose (fp);
852 flush_res = fflush (fp);
853 if (flush_res == EOF)
856 /* If get_contents couldn't write to fp, bail out. */
859 logprintf (LOG_NOTQUIET, _("%s: %s, closing control connection.\n"),
860 u->local, strerror (errno));
862 rbuf_uninitialize (&con->rbuf);
867 logprintf (LOG_NOTQUIET, _("%s (%s) - Data connection: %s; "),
868 tms, tmrate, strerror (errno));
869 if (opt.server_response)
870 logputs (LOG_ALWAYS, "\n");
873 /* Get the server to tell us if everything is retrieved. */
874 err = ftp_response (&con->rbuf, &respline);
875 /* ...and empty the buffer. */
876 rbuf_discard (&con->rbuf);
880 /* The control connection is decidedly closed. Print the time
881 only if it hasn't already been printed. */
883 logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
884 logputs (LOG_NOTQUIET, _("Control connection closed.\n"));
885 /* If there is an error on the control connection, close it, but
886 return FTPRETRINT, since there is a possibility that the
887 whole file was retrieved nevertheless (but that is for
888 ftp_loop_internal to decide). */
890 rbuf_uninitialize (&con->rbuf);
893 /* If retrieval failed for any reason, return FTPRETRINT, but do not
894 close socket, since the control connection is still alive. If
895 there is something wrong with the control connection, it will
896 become apparent later. */
897 if (*respline != '2')
901 logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
902 logputs (LOG_NOTQUIET, _("Data transfer aborted.\n"));
909 /* What now? The data connection was erroneous, whereas the
910 response says everything is OK. We shall play it safe. */
914 if (!(cmd & LEAVE_PENDING))
916 /* I should probably send 'QUIT' and check for a reply, but this
917 is faster. #### Is it OK, though? */
919 rbuf_uninitialize (&con->rbuf);
921 /* If it was a listing, and opt.server_response is true,
923 if (opt.server_response && (con->cmd & DO_LIST))
925 mkalldirs (u->local);
926 fp = fopen (u->local, "r");
928 logprintf (LOG_ALWAYS, "%s: %s\n", u->local, strerror (errno));
932 /* The lines are being read with read_whole_line because of
933 no-buffering on opt.lfile. */
934 while ((line = read_whole_line (fp)))
936 logprintf (LOG_ALWAYS, "%s\n", line);
941 } /* con->cmd & DO_LIST && server_response */
946 /* A one-file FTP loop. This is the part where FTP retrieval is
947 retried, and retried, and retried, and...
949 This loop either gets commands from con, or (if ON_YOUR_OWN is
950 set), makes them up to retrieve the file given by the URL. */
952 ftp_loop_internal (struct urlinfo *u, struct fileinfo *f, ccon *con)
956 char *tms, *tmrate, *locf;
961 u->local = url_filename (u);
963 if (opt.noclobber && file_exists_p (u->local))
965 logprintf (LOG_VERBOSE,
966 _("File `%s' already there, not retrieving.\n"), u->local);
967 /* If the file is there, we suppose it's retrieved OK. */
971 /* Remove it if it's a link. */
972 remove_link (u->local);
973 if (!opt.output_document)
976 locf = opt.output_document;
980 if (con->st & ON_YOUR_OWN)
981 con->st = ON_YOUR_OWN;
983 orig_lp = con->cmd & LEAVE_PENDING ? 1 : 0;
988 /* Increment the pass counter. */
990 sleep_between_retrievals (count);
991 if (con->st & ON_YOUR_OWN)
994 con->cmd |= (DO_RETR | LEAVE_PENDING);
995 if (rbuf_initialized_p (&con->rbuf))
996 con->cmd &= ~ (DO_LOGIN | DO_CWD);
998 con->cmd |= (DO_LOGIN | DO_CWD);
1000 else /* not on your own */
1002 if (rbuf_initialized_p (&con->rbuf))
1003 con->cmd &= ~DO_LOGIN;
1005 con->cmd |= DO_LOGIN;
1006 if (con->st & DONE_CWD)
1007 con->cmd &= ~DO_CWD;
1011 /* Assume no restarting. */
1013 if ((count > 1 || opt.always_rest)
1014 && !(con->cmd & DO_LIST)
1015 && file_exists_p (u->local))
1016 if (stat (u->local, &st) == 0)
1017 restval = st.st_size;
1018 /* Get the current time string. */
1019 tms = time_str (NULL);
1020 /* Print fetch message, if opt.verbose. */
1023 char *hurl = str_url (u->proxy ? u->proxy : u, 1);
1027 sprintf (tmp, _("(try:%2d)"), count);
1028 logprintf (LOG_VERBOSE, "--%s-- %s\n %s => `%s'\n",
1029 tms, hurl, tmp, locf);
1031 ws_changetitle (hurl, 1);
1035 /* Send getftp the proper length, if fileinfo was provided. */
1040 err = getftp (u, &len, restval, con);
1042 tms = time_str (NULL);
1043 tmrate = rate (len - restval, con->dltime);
1045 if (!rbuf_initialized_p (&con->rbuf))
1046 con->st &= ~DONE_CWD;
1048 con->st |= DONE_CWD;
1052 case HOSTERR: case CONREFUSED: case FWRITEERR: case FOPENERR:
1053 case FTPNSFOD: case FTPLOGINC: case FTPNOPASV:
1054 /* Fatal errors, give up. */
1057 case CONSOCKERR: case CONERROR: case FTPSRVERR: case FTPRERR:
1058 case WRITEFAILED: case FTPUNKNOWNTYPE: case CONPORTERR:
1059 case BINDERR: case LISTENERR: case ACCEPTERR:
1060 case FTPPORTERR: case FTPLOGREFUSED: case FTPINVPASV:
1061 printwhat (count, opt.ntry);
1062 /* non-fatal errors */
1066 /* If the control connection was closed, the retrieval
1067 will be considered OK if f->size == len. */
1068 if (!f || len != f->size)
1070 printwhat (count, opt.ntry);
1082 /* If we get out of the switch above without continue'ing, we've
1083 successfully downloaded a file. Remember this fact. */
1084 downloaded_file(FILE_DOWNLOADED_NORMALLY, locf);
1086 if (con->st & ON_YOUR_OWN)
1088 CLOSE (RBUF_FD (&con->rbuf));
1089 rbuf_uninitialize (&con->rbuf);
1091 logprintf (LOG_VERBOSE, _("%s (%s) - `%s' saved [%ld]\n\n"),
1092 tms, tmrate, locf, len);
1093 if (!opt.verbose && !opt.quiet)
1095 /* Need to hide the password from the URL. The `if' is here
1096 so that we don't do the needless allocation every
1098 char *hurl = str_url (u->proxy ? u->proxy : u, 1);
1099 logprintf (LOG_NONVERBOSE, "%s URL: %s [%ld] -> \"%s\" [%d]\n",
1100 tms, hurl, len, locf, count);
1104 if ((con->cmd & DO_LIST))
1105 /* This is a directory listing file. */
1107 if (!opt.remove_listing)
1108 /* --dont-remove-listing was specified, so do count this towards the
1109 number of bytes and files downloaded. */
1111 downloaded_increase (len);
1115 /* Deletion of listing files is not controlled by --delete-after, but
1116 by the more specific option --dont-remove-listing, and the code
1117 to do this deletion is in another function. */
1120 /* This is not a directory listing file. */
1122 /* Unlike directory listing files, don't pretend normal files weren't
1123 downloaded if they're going to be deleted. People seeding proxies,
1124 for instance, may want to know how many bytes and files they've
1125 downloaded through it. */
1126 downloaded_increase (len);
1129 if (opt.delete_after)
1131 DEBUGP (("Removing file due to --delete-after in"
1132 " ftp_loop_internal():\n"));
1133 logprintf (LOG_VERBOSE, _("Removing %s.\n"), locf);
1135 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1139 /* Restore the original leave-pendingness. */
1141 con->cmd |= LEAVE_PENDING;
1143 con->cmd &= ~LEAVE_PENDING;
1145 } while (!opt.ntry || (count < opt.ntry));
1147 if (rbuf_initialized_p (&con->rbuf) && (con->st & ON_YOUR_OWN))
1149 CLOSE (RBUF_FD (&con->rbuf));
1150 rbuf_uninitialize (&con->rbuf);
1155 /* Return the directory listing in a reusable format. The directory
1156 is specifed in u->dir. */
1157 static struct fileinfo *
1158 ftp_get_listing (struct urlinfo *u, ccon *con)
1162 char *olocal = u->local;
1163 char *list_filename, *ofile;
1165 con->st &= ~ON_YOUR_OWN;
1166 con->cmd |= (DO_LIST | LEAVE_PENDING);
1167 con->cmd &= ~DO_RETR;
1168 /* Get the listing filename. */
1170 u->file = LIST_FILENAME;
1171 list_filename = url_filename (u);
1173 u->local = list_filename;
1174 DEBUGP ((_("Using `%s' as listing tmp file.\n"), list_filename));
1175 err = ftp_loop_internal (u, NULL, con);
1178 f = ftp_parse_ls (list_filename, host_type);
1181 if (opt.remove_listing)
1183 if (unlink (list_filename))
1184 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1186 logprintf (LOG_VERBOSE, _("Removed `%s'.\n"), list_filename);
1188 xfree (list_filename);
1189 con->cmd &= ~DO_LIST;
1193 static uerr_t ftp_retrieve_dirs PARAMS ((struct urlinfo *, struct fileinfo *,
1195 static uerr_t ftp_retrieve_glob PARAMS ((struct urlinfo *, ccon *, int));
1196 static struct fileinfo *delelement PARAMS ((struct fileinfo *,
1197 struct fileinfo **));
1198 static void freefileinfo PARAMS ((struct fileinfo *f));
1200 /* Retrieve a list of files given in struct fileinfo linked list. If
1201 a file is a symbolic link, do not retrieve it, but rather try to
1202 set up a similar link on the local disk, if the symlinks are
1205 If opt.recursive is set, after all files have been retrieved,
1206 ftp_retrieve_dirs will be called to retrieve the directories. */
1208 ftp_retrieve_list (struct urlinfo *u, struct fileinfo *f, ccon *con)
1210 static int depth = 0;
1212 char *olocal, *ofile;
1213 struct fileinfo *orig;
1218 /* Increase the depth. */
1220 if (opt.reclevel != INFINITE_RECURSION && depth > opt.reclevel)
1222 DEBUGP ((_("Recursion depth %d exceeded max. depth %d.\n"),
1223 depth, opt.reclevel));
1231 con->st &= ~ON_YOUR_OWN;
1232 if (!(con->st & DONE_CWD))
1235 con->cmd &= ~DO_CWD;
1236 con->cmd |= (DO_RETR | LEAVE_PENDING);
1238 if (!rbuf_initialized_p (&con->rbuf))
1239 con->cmd |= DO_LOGIN;
1241 con->cmd &= ~DO_LOGIN;
1243 err = RETROK; /* in case it's not used */
1247 if (downloaded_exceeds_quota ())
1255 u->local = url_filename (u);
1259 if (opt.timestamping && f->type == FT_PLAINFILE)
1262 /* If conversion of HTML files retrieved via FTP is ever implemented,
1263 we'll need to stat() <file>.orig here when -K has been specified.
1264 I'm not implementing it now since files on an FTP server are much
1265 more likely than files on an HTTP server to legitimately have a
1267 if (!stat (u->local, &st))
1269 /* Else, get it from the file. */
1270 local_size = st.st_size;
1272 if (local_size == f->size && tml >= f->tstamp)
1274 logprintf (LOG_VERBOSE, _("\
1275 Server file no newer than local file `%s' -- not retrieving.\n\n"), u->local);
1278 else if (local_size != f->size)
1280 if (host_type == ST_VMS)
1282 logprintf (LOG_VERBOSE, _("\
1283 Cannot compare sizes, remote system is VMS.\n"));
1288 logprintf (LOG_VERBOSE, _("\
1289 The sizes do not match (local %ld) -- retrieving.\n"), local_size);
1293 } /* opt.timestamping && f->type == FT_PLAINFILE */
1297 /* If opt.retr_symlinks is defined, we treat symlinks as
1298 if they were normal files. There is currently no way
1299 to distinguish whether they might be directories, and
1301 if (!opt.retr_symlinks)
1305 logputs (LOG_NOTQUIET,
1306 _("Invalid name of the symlink, skipping.\n"));
1310 /* Check whether we already have the correct
1312 int rc = lstat (u->local, &st);
1315 size_t len = strlen (f->linkto) + 1;
1316 if (S_ISLNK (st.st_mode))
1318 char *link_target = (char *)alloca (len);
1319 size_t n = readlink (u->local, link_target, len);
1321 && (memcmp (link_target, f->linkto, n) == 0))
1323 logprintf (LOG_VERBOSE, _("\
1324 Already have correct symlink %s -> %s\n\n"),
1325 u->local, f->linkto);
1331 logprintf (LOG_VERBOSE, _("Creating symlink %s -> %s\n"),
1332 u->local, f->linkto);
1333 /* Unlink before creating symlink! */
1335 if (symlink (f->linkto, u->local) == -1)
1336 logprintf (LOG_NOTQUIET, "symlink: %s\n",
1338 logputs (LOG_VERBOSE, "\n");
1339 } /* have f->linkto */
1340 #else /* not HAVE_SYMLINK */
1341 logprintf (LOG_NOTQUIET,
1342 _("Symlinks not supported, skipping symlink `%s'.\n"),
1344 #endif /* not HAVE_SYMLINK */
1346 else /* opt.retr_symlinks */
1349 err = ftp_loop_internal (u, f, con);
1350 } /* opt.retr_symlinks */
1354 logprintf (LOG_NOTQUIET, _("Skipping directory `%s'.\n"),
1358 /* Call the retrieve loop. */
1360 err = ftp_loop_internal (u, f, con);
1363 logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
1368 /* Set the time-stamp information to the local file. Symlinks
1369 are not to be stamped because it sets the stamp on the
1371 if (!(f->type == FT_SYMLINK && !opt.retr_symlinks)
1374 && file_exists_p (u->local))
1376 /* #### This code repeats in http.c and ftp.c. Move it to a
1378 const char *fl = NULL;
1379 if (opt.output_document)
1381 if (opt.od_known_regular)
1382 fl = opt.output_document;
1387 touch (fl, f->tstamp);
1389 else if (f->tstamp == -1)
1390 logprintf (LOG_NOTQUIET, _("%s: corrupt time-stamp.\n"), u->local);
1392 if (f->perms && f->type == FT_PLAINFILE && dlthis)
1393 chmod (u->local, f->perms);
1395 DEBUGP (("Unrecognized permissions for %s.\n", u->local));
1400 /* Break on fatals. */
1401 if (err == QUOTEXC || err == HOSTERR || err == FWRITEERR)
1403 con->cmd &= ~ (DO_CWD | DO_LOGIN);
1406 /* We do not want to call ftp_retrieve_dirs here */
1407 if (opt.recursive &&
1408 !(opt.reclevel != INFINITE_RECURSION && depth >= opt.reclevel))
1409 err = ftp_retrieve_dirs (u, orig, con);
1410 else if (opt.recursive)
1411 DEBUGP ((_("Will not retrieve dirs since depth is %d (max %d).\n"),
1412 depth, opt.reclevel));
1417 /* Retrieve the directories given in a file list. This function works
1418 by simply going through the linked list and calling
1419 ftp_retrieve_glob on each directory entry. The function knows
1420 about excluded directories. */
1422 ftp_retrieve_dirs (struct urlinfo *u, struct fileinfo *f, ccon *con)
1425 char *current_container = NULL;
1426 int current_length = 0;
1428 for (; f; f = f->next)
1432 if (downloaded_exceeds_quota ())
1434 if (f->type != FT_DIRECTORY)
1437 len = 1 + strlen (u->dir) + 1 + strlen (f->name) + 1;
1438 /* Allocate u->dir off stack, but reallocate only if a larger
1439 string is needed. */
1440 if (len > current_length)
1441 current_container = (char *)alloca (len);
1442 u->dir = current_container;
1443 /* When retrieving recursively, all directories must be
1444 absolute. This restriction will (hopefully!) be lifted in
1446 sprintf (u->dir, "/%s%s%s", odir + (*odir == '/'),
1447 (!*odir || (*odir == '/' && !* (odir + 1))) ? "" : "/", f->name);
1448 if (!accdir (u->dir, ALLABS))
1450 logprintf (LOG_VERBOSE, _("\
1451 Not descending to `%s' as it is excluded/not-included.\n"), u->dir);
1455 con->st &= ~DONE_CWD;
1456 ftp_retrieve_glob (u, con, GETALL);
1457 /* Set the time-stamp? */
1460 if (opt.quota && opt.downloaded > opt.quota)
1467 /* A near-top-level function to retrieve the files in a directory.
1468 The function calls ftp_get_listing, to get a linked list of files.
1469 Then it weeds out the file names that do not match the pattern.
1470 ftp_retrieve_list is called with this updated list as an argument.
1472 If the argument ACTION is GETONE, just download the file (but first
1473 get the listing, so that the time-stamp is heeded); if it's GLOBALL,
1474 use globbing; if it's GETALL, download the whole directory. */
1476 ftp_retrieve_glob (struct urlinfo *u, ccon *con, int action)
1478 struct fileinfo *orig, *start;
1481 con->cmd |= LEAVE_PENDING;
1483 orig = ftp_get_listing (u, con);
1485 /* First: weed out that do not conform the global rules given in
1486 opt.accepts and opt.rejects. */
1487 if (opt.accepts || opt.rejects)
1489 struct fileinfo *f = orig;
1493 if (f->type != FT_DIRECTORY && !acceptable (f->name))
1495 logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"), f->name);
1496 f = delelement (f, &start);
1502 /* Now weed out the files that do not match our globbing pattern.
1503 If we are dealing with a globbing pattern, that is. */
1504 if (*u->file && (action == GLOBALL || action == GETONE))
1507 struct fileinfo *f = start;
1511 matchres = fnmatch (u->file, f->name, 0);
1514 logprintf (LOG_NOTQUIET, "%s: %s\n", u->local,
1518 if (matchres == FNM_NOMATCH)
1519 f = delelement (f, &start); /* delete the element from the list */
1521 f = f->next; /* leave the element in the list */
1525 freefileinfo (start);
1526 return RETRBADPATTERN;
1532 /* Just get everything. */
1533 ftp_retrieve_list (u, start, con);
1537 if (action == GLOBALL)
1540 /* #### This message SUCKS. We should see what was the
1541 reason that nothing was retrieved. */
1542 logprintf (LOG_VERBOSE, _("No matches on pattern `%s'.\n"), u->file);
1544 else /* GETONE or GETALL */
1546 /* Let's try retrieving it anyway. */
1547 con->st |= ON_YOUR_OWN;
1548 res = ftp_loop_internal (u, NULL, con);
1552 freefileinfo (start);
1553 if (downloaded_exceeds_quota ())
1556 /* #### Should we return `res' here? */
1560 /* The wrapper that calls an appropriate routine according to contents
1561 of URL. Inherently, its capabilities are limited on what can be
1562 encoded into a URL. */
1564 ftp_loop (struct urlinfo *u, int *dt)
1566 ccon con; /* FTP connection */
1571 rbuf_uninitialize (&con.rbuf);
1572 con.st = ON_YOUR_OWN;
1573 res = RETROK; /* in case it's not used */
1575 /* If the file name is empty, the user probably wants a directory
1576 index. We'll provide one, properly HTML-ized. Unless
1577 opt.htmlify is 0, of course. :-) */
1578 if (!*u->file && !opt.recursive)
1580 struct fileinfo *f = ftp_get_listing (u, &con);
1586 char *filename = (opt.output_document
1587 ? xstrdup (opt.output_document)
1588 : (u->local ? xstrdup (u->local)
1589 : url_filename (u)));
1590 res = ftp_index (filename, u, f);
1591 if (res == FTPOK && opt.verbose)
1593 if (!opt.output_document)
1597 if (stat (filename, &st) == 0)
1601 logprintf (LOG_NOTQUIET,
1602 _("Wrote HTML-ized index to `%s' [%ld].\n"),
1606 logprintf (LOG_NOTQUIET,
1607 _("Wrote HTML-ized index to `%s'.\n"),
1617 int wild = has_wildcards_p (u->file);
1618 if ((opt.ftp_glob && wild) || opt.recursive || opt.timestamping)
1620 /* ftp_retrieve_glob is a catch-all function that gets called
1621 if we need globbing, time-stamping or recursion. Its
1622 third argument is just what we really need. */
1623 ftp_retrieve_glob (u, &con,
1624 (opt.ftp_glob && wild) ? GLOBALL : GETONE);
1627 res = ftp_loop_internal (u, NULL, &con);
1633 /* If a connection was left, quench it. */
1634 if (rbuf_initialized_p (&con.rbuf))
1635 CLOSE (RBUF_FD (&con.rbuf));
1641 /* Delete an element from the fileinfo linked list. Returns the
1642 address of the next element, or NULL if the list is exhausted. It
1643 can modify the start of the list. */
1644 static struct fileinfo *
1645 delelement (struct fileinfo *f, struct fileinfo **start)
1647 struct fileinfo *prev = f->prev;
1648 struct fileinfo *next = f->next;
1651 FREE_MAYBE (f->linkto);
1663 /* Free the fileinfo linked list of files. */
1665 freefileinfo (struct fileinfo *f)
1669 struct fileinfo *next = f->next;