/* File retrieval.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of GNU Wget.
You should have received a copy of the GNU General Public License
along with Wget. If not, see <http://www.gnu.org/licenses/>.
-In addition, as a special exception, the Free Software Foundation
-gives permission to link the code of its release of Wget with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version. */
+Additional permission under GNU GPL version 3 section 7
-#include <config.h>
+If you modify this program, or any covered work, by linking or
+combining it with the OpenSSL project's OpenSSL library (or a
+modified version of that library), containing parts covered by the
+terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
+grants you additional permission to convey the resulting work.
+Corresponding Source for a non-source form of such a combination
+shall include the source code for the parts of OpenSSL used as well
+as that of the covered work. */
+
+#include "wget.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
-#include "wget.h"
#include "utils.h"
#include "retr.h"
#include "progress.h"
static int
write_data (FILE *out, const char *buf, int bufsize, wgint *skip,
- wgint *written)
+ wgint *written, int flags)
{
+ static int cr_pending = 0; /* Found CR in ASCII FTP data. */
+
if (!out)
return 1;
if (*skip > bufsize)
return 1;
}
- fwrite (buf, 1, bufsize, out);
- *written += bufsize;
+/* Note: This code assumes that "\n" is the universal line ending
+ character, as on UNIX and VMS. If this is not true, then here's
+ where to change it.
+*/
+
+#if 1
+# define EOL_STRING "\n"
+#else /* 1 */
+# define EOL_STRING "\r\n"
+#endif /* 1 [else] */
+#define EOL_STRING_LEN (sizeof( EOL_STRING)- 1)
+
+ if (flags & rb_ftp_ascii)
+ {
+ const char *bufend;
+
+ /* ASCII transfer. Put out lines delimited by CRLF. */
+ bufend = buf+ bufsize;
+ while (buf < bufend)
+ {
+ /* If CR, put out any pending CR, then set CR-pending flag. */
+ if (*buf == '\r')
+ {
+ if (cr_pending)
+ {
+ fwrite ("\r", 1, 1, out);
+ *written += 1;
+ }
+ cr_pending = 1;
+ buf++;
+ continue;
+ }
+
+ if (cr_pending)
+ {
+ if (*buf == '\n')
+ {
+ /* Found FTP EOL (CRLF). Put out local EOL. */
+ fwrite (EOL_STRING, 1, EOL_STRING_LEN, out);
+ *written += EOL_STRING_LEN;
+ }
+ else
+ {
+ /* Normal character. Put out pending CR and it. */
+ fwrite ("\r", 1, 1, out);
+ fwrite (buf, 1, 1, out);
+ *written += 2;
+ }
+ buf++;
+ cr_pending = 0;
+ }
+ else
+ {
+ /* Normal character. Put it out. */
+ fwrite (buf, 1, 1, out);
+ *written += 1;
+ buf++;
+ }
+ }
+ }
+ else
+ {
+ /* Image transfer. Put out buffer. */
+ fwrite (buf, 1, bufsize, out);
+ *written += bufsize;
+ }
/* Immediately flush the downloaded data. This should not hinder
performance: fast downloads will arrive in large 16K chunks
(which stdio would write out immediately anyway), and slow
downloads wouldn't be limited by disk speed. */
+
+ /* 2005-04-20 SMS.
+ Perhaps it shouldn't hinder performance, but it sure does, at least
+ on VMS (more than 2X). Rather than speculate on what it should or
+ shouldn't do, it might make more sense to test it. Even better, it
+ might be nice to explain what possible benefit it could offer, as
+ it appears to be a clear invitation to poor performance with no
+ actual justification. (Also, why 16K? Anyone test other values?)
+ */
+#ifndef __VMS
fflush (out);
+#endif /* ndef __VMS */
return !ferror (out);
}
if (ret > 0)
{
sum_read += ret;
- if (!write_data (out, dlbuf, ret, &skip, &sum_written))
+ if (!write_data (out, dlbuf, ret, &skip, &sum_written, flags))
{
ret = -2;
goto out;