]> sjero.net Git - wget/blobdiff - src/retr.c
Steven Schweda's VMS patch.
[wget] / src / retr.c
index 3234286baa8ea48c16a97d62ec52a49561ccc821..b5a10e2a03bc7cdc05c7182a0a73d3f0e5434e35 100644 (file)
@@ -1,6 +1,6 @@
 /* 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.
 
@@ -17,17 +17,18 @@ GNU General Public License for more details.
 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>
@@ -38,7 +39,6 @@ so, delete this exception statement from your version.  */
 #include <string.h>
 #include <assert.h>
 
-#include "wget.h"
 #include "utils.h"
 #include "retr.h"
 #include "progress.h"
@@ -141,8 +141,10 @@ limit_bandwidth (wgint bytes, struct ptimer *timer)
 
 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)
@@ -159,14 +161,89 @@ write_data (FILE *out, const char *buf, int bufsize, wgint *skip,
         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);
 }
 
@@ -296,7 +373,7 @@ fd_read_body (int fd, FILE *out, wgint toread, wgint startpos,
       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;