]> sjero.net Git - wget/blobdiff - src/http.c
Rename --html-extension to --adjust-extension.
[wget] / src / http.c
index c3adbf40755150d2ab158f674941302b8dd521cb..d24db5fc38f3393ef6937c32e1ba03e3e6eba24b 100644 (file)
@@ -66,6 +66,10 @@ as that of the covered work.  */
 #include "test.h"
 #endif
 
+#ifdef __VMS
+# include "vms.h"
+#endif /* def __VMS */
+
 extern char *version_string;
 
 /* Forward decls. */
@@ -1341,13 +1345,27 @@ free_hstat (struct http_stat *hs)
    && (c_isspace (line[sizeof (string_constant) - 1])                      \
        || !line[sizeof (string_constant) - 1]))
 
+#ifdef __VMS
+#define SET_USER_AGENT(req) do {                                         \
+  if (!opt.useragent)                                                    \
+    request_set_header (req, "User-Agent",                               \
+                        aprintf ("Wget/%s (VMS %s %s)",                  \
+                        version_string, vms_arch(), vms_vers()),         \
+                        rel_value);                                      \
+  else if (*opt.useragent)                                               \
+    request_set_header (req, "User-Agent", opt.useragent, rel_none);     \
+} while (0)
+#else /* def __VMS */
 #define SET_USER_AGENT(req) do {                                         \
   if (!opt.useragent)                                                    \
     request_set_header (req, "User-Agent",                               \
-                        aprintf ("Wget/%s", version_string), rel_value); \
+                        aprintf ("Wget/%s (%s)",                         \
+                        version_string, OS_TYPE),                        \
+                        rel_value);                                      \
   else if (*opt.useragent)                                               \
     request_set_header (req, "User-Agent", opt.useragent, rel_none);     \
 } while (0)
+#endif /* def __VMS [else] */
 
 /* The flags that allow clobbering the file (opening with "wb").
    Defined here to avoid repetition later.  #### This will require
@@ -1366,7 +1384,8 @@ free_hstat (struct http_stat *hs)
    If PROXY is non-NULL, the connection will be made to the proxy
    server, and u->url will be requested.  */
 static uerr_t
-gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
+gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy,
+         struct iri *iri)
 {
   struct request *req;
 
@@ -1743,7 +1762,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
 
       if (conn->scheme == SCHEME_HTTPS)
         {
-          if (!ssl_connect (sock) || !ssl_check_certificate (sock, u->host))
+          if (!ssl_connect_wget (sock) || !ssl_check_certificate (sock, u->host))
             {
               fd_close (sock);
               return CONSSLERR;
@@ -1885,6 +1904,9 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
                   register_basic_auth_host (u->host);
                 }
               xfree (pth);
+              xfree_null (message);
+              resp_free (resp);
+              xfree (head);
               goto retry_with_auth;
             }
           else
@@ -1895,6 +1917,9 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
         }
       logputs (LOG_NOTQUIET, _("Authorization failed.\n"));
       request_free (req);
+      xfree_null (message);
+      resp_free (resp);
+      xfree (head);
       return AUTHFAILED;
     }
   else /* statcode != HTTP_STATUS_UNAUTHORIZED */
@@ -1919,7 +1944,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
           hs->local_file = url_file_name (u);
         }
     }
-  
+
   /* TODO: perform this check only once. */
   if (!hs->existence_checked && file_exists_p (hs->local_file))
     {
@@ -1938,6 +1963,8 @@ File %s already there; not retrieving.\n\n"), quote (hs->local_file));
           if (has_html_suffix_p (hs->local_file))
             *dt |= TEXTHTML;
 
+          xfree (head);
+          xfree_null (message);
           return RETRUNNEEDED;
         }
       else if (!ALLOW_CLOBBER)
@@ -1955,7 +1982,7 @@ File %s already there; not retrieving.\n\n"), quote (hs->local_file));
   if (opt.timestamping && !hs->timestamp_checked)
     {
       size_t filename_len = strlen (hs->local_file);
-      char *filename_plus_orig_suffix = alloca (filename_len + sizeof (".orig"));
+      char *filename_plus_orig_suffix = alloca (filename_len + sizeof (ORIG_SFX));
       bool local_dot_orig_file_exists = false;
       char *local_filename = NULL;
       struct_stat st;
@@ -1980,7 +2007,7 @@ File %s already there; not retrieving.\n\n"), quote (hs->local_file));
              --hniksic */
           memcpy (filename_plus_orig_suffix, hs->local_file, filename_len);
           memcpy (filename_plus_orig_suffix + filename_len,
-                  ".orig", sizeof (".orig"));
+                  ORIG_SFX, sizeof (ORIG_SFX));
 
           /* Try to stat() the .orig file. */
           if (stat (filename_plus_orig_suffix, &st) == 0)
@@ -1988,7 +2015,7 @@ File %s already there; not retrieving.\n\n"), quote (hs->local_file));
               local_dot_orig_file_exists = true;
               local_filename = filename_plus_orig_suffix;
             }
-        }      
+        }
 
       if (!local_dot_orig_file_exists)
         /* Couldn't stat() <file>.orig, so try to stat() <file>. */
@@ -2053,9 +2080,20 @@ File %s already there; not retrieving.\n\n"), quote (hs->local_file));
       char *tmp = strchr (type, ';');
       if (tmp)
         {
+          /* sXXXav: only needed if IRI support is enabled */
+          char *tmp2 = tmp + 1;
+
           while (tmp > type && c_isspace (tmp[-1]))
             --tmp;
           *tmp = '\0';
+
+          /* Try to get remote encoding if needed */
+          if (opt.enable_iri && !opt.encoding_remote)
+            {
+              tmp = parse_charset (tmp2);
+              if (tmp)
+                set_content_encoding (iri, tmp);
+            }
         }
     }
   hs->newloc = resp_header_strdup (resp, "Location");
@@ -2116,6 +2154,7 @@ File %s already there; not retrieving.\n\n"), quote (hs->local_file));
           else
             CLOSE_INVALIDATE (sock);
           xfree_null (type);
+          xfree (head);
           return NEWLOCATION;
         }
     }
@@ -2136,10 +2175,10 @@ File %s already there; not retrieving.\n\n"), quote (hs->local_file));
   else
     *dt &= ~TEXTCSS;
 
-  if (opt.html_extension)
+  if (opt.adjust_extension)
     {
       if (*dt & TEXTHTML)
-        /* -E / --html-extension / html_extension = on was specified,
+        /* -E / --adjust-extension / adjust_extension = on was specified,
            and this is a text/html file.  If some case-insensitive
            variation on ".htm[l]" isn't already the file's suffix,
            tack on ".html". */
@@ -2171,6 +2210,7 @@ File %s already there; not retrieving.\n\n"), quote (hs->local_file));
       xfree_null (type);
       CLOSE_INVALIDATE (sock);        /* would be CLOSE_FINISH, but there
                                    might be more bytes in the body. */
+      xfree (head);
       return RETRUNNEEDED;
     }
   if ((contrange != 0 && contrange != hs->restval)
@@ -2180,6 +2220,7 @@ File %s already there; not retrieving.\n\n"), quote (hs->local_file));
          Bail out.  */
       xfree_null (type);
       CLOSE_INVALIDATE (sock);
+      xfree (head);
       return RANGEERR;
     }
   if (contlen == -1)
@@ -2243,9 +2284,20 @@ File %s already there; not retrieving.\n\n"), quote (hs->local_file));
         CLOSE_FINISH (sock);
       else
         CLOSE_INVALIDATE (sock);
+      xfree (head);
       return RETRFINISHED;
     }
 
+/* 2005-06-17 SMS.
+   For VMS, define common fopen() optional arguments.
+*/
+#ifdef __VMS
+# define FOPEN_OPT_ARGS "fop=sqo", "acc", acc_cb, &open_id
+# define FOPEN_BIN_FLAG 3
+#else /* def __VMS */
+# define FOPEN_BIN_FLAG 1
+#endif /* def __VMS [else] */
+
   /* Open the local file.  */
   if (!output_stream)
     {
@@ -2253,9 +2305,27 @@ File %s already there; not retrieving.\n\n"), quote (hs->local_file));
       if (opt.backups)
         rotate_backups (hs->local_file);
       if (hs->restval)
-        fp = fopen (hs->local_file, "ab");
+        {
+#ifdef __VMS
+          int open_id;
+
+          open_id = 21;
+          fp = fopen (hs->local_file, "ab", FOPEN_OPT_ARGS);
+#else /* def __VMS */
+          fp = fopen (hs->local_file, "ab");
+#endif /* def __VMS [else] */
+        }
       else if (ALLOW_CLOBBER)
-        fp = fopen (hs->local_file, "wb");
+        {
+#ifdef __VMS
+          int open_id;
+
+          open_id = 22;
+          fp = fopen (hs->local_file, "wb", FOPEN_OPT_ARGS);
+#else /* def __VMS */
+          fp = fopen (hs->local_file, "wb");
+#endif /* def __VMS [else] */
+        }
       else
         {
           fp = fopen_excl (hs->local_file, true);
@@ -2269,6 +2339,7 @@ File %s already there; not retrieving.\n\n"), quote (hs->local_file));
                          _("%s has sprung into existence.\n"),
                          hs->local_file);
               CLOSE_INVALIDATE (sock);
+              xfree (head);
               return FOPEN_EXCL_ERR;
             }
         }
@@ -2276,6 +2347,7 @@ File %s already there; not retrieving.\n\n"), quote (hs->local_file));
         {
           logprintf (LOG_NOTQUIET, "%s: %s\n", hs->local_file, strerror (errno));
           CLOSE_INVALIDATE (sock);
+          xfree (head);
           return FOPENERR;
         }
     }
@@ -2334,7 +2406,7 @@ File %s already there; not retrieving.\n\n"), quote (hs->local_file));
    retried, and retried, and retried, and...  */
 uerr_t
 http_loop (struct url *u, char **newloc, char **local_file, const char *referer,
-           int *dt, struct url *proxy)
+           int *dt, struct url *proxy, struct iri *iri)
 {
   int count;
   bool got_head = false;         /* used for time-stamping and filename detection */
@@ -2345,16 +2417,17 @@ http_loop (struct url *u, char **newloc, char **local_file, const char *referer,
   uerr_t err, ret = TRYLIMEXC;
   time_t tmr = -1;               /* remote time-stamp */
   struct http_stat hstat;        /* HTTP status */
-  struct_stat st;  
+  struct_stat st;
   bool send_head_first = true;
+  char *file_name;
 
   /* Assert that no value for *LOCAL_FILE was passed. */
   assert (local_file == NULL || *local_file == NULL);
-  
+
   /* Set LOCAL_FILE parameter. */
   if (local_file && opt.output_document)
     *local_file = HYPHENP (opt.output_document) ? NULL : xstrdup (opt.output_document);
-  
+
   /* Reset NEWLOC parameter. */
   *newloc = NULL;
 
@@ -2391,7 +2464,7 @@ http_loop (struct url *u, char **newloc, char **local_file, const char *referer,
          retrieve the file. But if the output_document was given, then this
          test was already done and the file didn't exist. Hence the !opt.output_document */
       logprintf (LOG_VERBOSE, _("\
-File %s already there; not retrieving.\n\n"), 
+File %s already there; not retrieving.\n\n"),
                  quote (hstat.local_file));
       /* If the file is there, we suppose it's retrieved OK.  */
       *dt |= RETROKF;
@@ -2407,10 +2480,10 @@ File %s already there; not retrieving.\n\n"),
 
   /* Reset the counter. */
   count = 0;
-  
+
   /* Reset the document type. */
   *dt = 0;
-  
+
   /* Skip preliminary HEAD request if we're not in spider mode AND
    * if -O was given or HTTP Content-Disposition support is disabled. */
   if (!opt.spider
@@ -2419,10 +2492,12 @@ File %s already there; not retrieving.\n\n"),
 
   /* Send preliminary HEAD request if -N is given and we have an existing 
    * destination file. */
-  if (opt.timestamping 
+  file_name = url_file_name (u);
+  if (opt.timestamping
       && !opt.content_disposition
-      && file_exists_p (url_file_name (u)))
+      && file_exists_p (file_name))
     send_head_first = true;
+  xfree (file_name);
   
   /* THE loop */
   do
@@ -2430,10 +2505,10 @@ File %s already there; not retrieving.\n\n"),
       /* Increment the pass counter.  */
       ++count;
       sleep_between_retrievals (count);
-      
+
       /* Get the current time string.  */
       tms = datetime_str (time (NULL));
-      
+
       if (opt.spider && !got_head)
         logprintf (LOG_VERBOSE, _("\
 Spider mode enabled. Check if remote file exists.\n"));
@@ -2442,20 +2517,20 @@ Spider mode enabled. Check if remote file exists.\n"));
       if (opt.verbose)
         {
           char *hurl = url_string (u, URL_AUTH_HIDE_PASSWD);
-          
-          if (count > 1) 
+
+          if (count > 1)
             {
               char tmp[256];
               sprintf (tmp, _("(try:%2d)"), count);
               logprintf (LOG_NOTQUIET, "--%s--  %s  %s\n",
                          tms, tmp, hurl);
             }
-          else 
+          else
             {
               logprintf (LOG_NOTQUIET, "--%s--  %s\n",
                          tms, hurl);
             }
-          
+
 #ifdef WINDOWS
           ws_changetitle (hurl);
 #endif
@@ -2465,7 +2540,7 @@ Spider mode enabled. Check if remote file exists.\n"));
       /* Default document type is empty.  However, if spider mode is
          on or time-stamping is employed, HEAD_ONLY commands is
          encoded within *dt.  */
-      if (send_head_first && !got_head) 
+      if (send_head_first && !got_head)
         *dt |= HEAD_ONLY;
       else
         *dt &= ~HEAD_ONLY;
@@ -2498,11 +2573,11 @@ Spider mode enabled. Check if remote file exists.\n"));
         *dt &= ~SEND_NOCACHE;
 
       /* Try fetching the document, or at least its head.  */
-      err = gethttp (u, &hstat, dt, proxy);
+      err = gethttp (u, &hstat, dt, proxy, iri);
 
       /* Time?  */
       tms = datetime_str (time (NULL));
-      
+
       /* Get the new location (with or without the redirection).  */
       if (hstat.newloc)
         *newloc = xstrdup (hstat.newloc);
@@ -2541,7 +2616,7 @@ Spider mode enabled. Check if remote file exists.\n"));
                          hstat.statcode);
               ret = WRONGCODE;
             }
-          else 
+          else
             {
               ret = NEWLOCATION;
             }
@@ -2557,7 +2632,7 @@ Spider mode enabled. Check if remote file exists.\n"));
           /* All possibilities should have been exhausted.  */
           abort ();
         }
-      
+
       if (!(*dt & RETROKF))
         {
           char *hurl = NULL;
@@ -2576,11 +2651,13 @@ Spider mode enabled. Check if remote file exists.\n"));
               continue;
             }
           /* Maybe we should always keep track of broken links, not just in
-           * spider mode.  */
-          else if (opt.spider)
+           * spider mode.
+           * Don't log error if it was UTF-8 encoded because we will try
+           * once unencoded. */
+          else if (opt.spider && !iri->utf8_encode)
             {
               /* #### Again: ugly ugly ugly! */
-              if (!hurl) 
+              if (!hurl)
                 hurl = url_string (u, URL_AUTH_HIDE_PASSWD);
               nonexisting_url (hurl);
               logprintf (LOG_NOTQUIET, _("\
@@ -2589,7 +2666,7 @@ Remote file does not exist -- broken link!!!\n"));
           else
             {
               logprintf (LOG_NOTQUIET, _("%s ERROR %d: %s.\n"),
-                         tms, hstat.statcode, 
+                         tms, hstat.statcode,
                          quotearg_style (escape_quoting_style, hstat.error));
             }
           logputs (LOG_VERBOSE, "\n");
@@ -2705,7 +2782,7 @@ Remote file exists.\n\n"));
                   if (finished)
                     {
                       logprintf (LOG_NONVERBOSE, 
-                                 _("%s URL:%s %2d %s\n"), 
+                                 _("%s URL: %s %2d %s\n"), 
                                  tms, u->url, hstat.statcode,
                                  hstat.message ? quotearg_style (escape_quoting_style, hstat.message) : "");
                       goto exit;
@@ -2733,7 +2810,7 @@ Remote file exists.\n\n"));
                   && hstat.remote_time && hstat.remote_time[0])
                 {
                   newtmr = http_atotm (hstat.remote_time);
-                  if (newtmr != -1)
+                  if (newtmr != (time_t)-1)
                     tmr = newtmr;
                 }
               touch (fl, tmr);
@@ -2935,6 +3012,7 @@ http_atotm (const char *time_string)
                                    Netscape cookie specification.) */
   };
   const char *oldlocale;
+  char savedlocale[256];
   size_t i;
   time_t ret = (time_t) -1;
 
@@ -2942,6 +3020,16 @@ http_atotm (const char *time_string)
      non-English locales, which we work around by temporarily setting
      locale to C before invoking strptime.  */
   oldlocale = setlocale (LC_TIME, NULL);
+  if (oldlocale)
+    {
+      size_t l = strlen (oldlocale);
+      if (l >= sizeof savedlocale)
+        savedlocale[0] = '\0';
+      else
+        memcpy (savedlocale, oldlocale, l);
+    }
+  else savedlocale[0] = '\0';
+
   setlocale (LC_TIME, "C");
 
   for (i = 0; i < countof (time_formats); i++)
@@ -2961,7 +3049,8 @@ http_atotm (const char *time_string)
     }
 
   /* Restore the previous locale. */
-  setlocale (LC_TIME, oldlocale);
+  if (savedlocale[0])
+    setlocale (LC_TIME, savedlocale);
 
   return ret;
 }