]> sjero.net Git - wget/blobdiff - src/url.c
[mq]: cfg-mk
[wget] / src / url.c
index 8f0672503f07fdfef8cde9b8b4093b4b63841c71..d0b94a98acfca46f73a89216905d21e5db3093c5 100644 (file)
--- a/src/url.c
+++ b/src/url.c
@@ -1,6 +1,6 @@
 /* URL handling.
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-   2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+   2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 
 This file is part of GNU Wget.
 
@@ -43,6 +43,10 @@ as that of the covered work.  */
 #include "url.h"
 #include "host.h"  /* for is_valid_ipv6_address */
 
+#ifdef __VMS
+#include "vms.h"
+#endif /* def __VMS */
+
 #ifdef TESTING
 #include "test.h"
 #endif
@@ -252,6 +256,15 @@ url_escape (const char *s)
   return url_escape_1 (s, urlchr_unsafe, false);
 }
 
+/* URL-escape the unsafe and reserved characters (see urlchr_table) in
+   a given string, returning a freshly allocated string.  */
+
+char *
+url_escape_unsafe_and_reserved (const char *s)
+{
+  return url_escape_1 (s, urlchr_unsafe|urlchr_reserved, false);
+}
+
 /* URL-escape the unsafe characters (see urlchr_table) in a given
    string.  If no characters are unsafe, S is returned.  */
 
@@ -619,18 +632,20 @@ static const char *parse_errors[] = {
 #define PE_NO_ERROR                     0
   N_("No error"),
 #define PE_UNSUPPORTED_SCHEME           1
-  N_("Unsupported scheme %s"),
-#define PE_INVALID_HOST_NAME            2
+  N_("Unsupported scheme %s"), /* support for format token only here */
+#define PE_MISSING_SCHEME               2
+  N_("Scheme missing"),
+#define PE_INVALID_HOST_NAME            3
   N_("Invalid host name"),
-#define PE_BAD_PORT_NUMBER              3
+#define PE_BAD_PORT_NUMBER              4
   N_("Bad port number"),
-#define PE_INVALID_USER_NAME            4
+#define PE_INVALID_USER_NAME            5
   N_("Invalid user name"),
-#define PE_UNTERMINATED_IPV6_ADDRESS    5
+#define PE_UNTERMINATED_IPV6_ADDRESS    6
   N_("Unterminated IPv6 numeric address"),
-#define PE_IPV6_NOT_SUPPORTED           6
+#define PE_IPV6_NOT_SUPPORTED           7
   N_("IPv6 addresses not supported"),
-#define PE_INVALID_IPV6_ADDRESS         7
+#define PE_INVALID_IPV6_ADDRESS         8
   N_("Invalid IPv6 numeric address")
 };
 
@@ -659,14 +674,18 @@ url_parse (const char *url, int *error, struct iri *iri, bool percent_encode)
   int port;
   char *user = NULL, *passwd = NULL;
 
-  char *url_encoded = NULL, *new_url = NULL;
+  const char *url_encoded = NULL;
+  char *new_url = NULL;
 
   int error_code;
 
   scheme = url_scheme (url);
   if (scheme == SCHEME_INVALID)
     {
-      error_code = PE_UNSUPPORTED_SCHEME;
+      if (url_has_scheme (url))
+        error_code = PE_UNSUPPORTED_SCHEME;
+      else
+        error_code = PE_MISSING_SCHEME;
       goto error;
     }
 
@@ -683,7 +702,7 @@ url_parse (const char *url, int *error, struct iri *iri, bool percent_encode)
   if (percent_encode)
     url_encoded = reencode_escapes (new_url ? new_url : url);
   else
-     url_encoded = new_url ? new_url : url;
+    url_encoded = new_url ? new_url : url;
 
   p = url_encoded;
 
@@ -895,7 +914,7 @@ url_parse (const char *url, int *error, struct iri *iri, bool percent_encode)
       if (url_encoded == url)
         u->url = xstrdup (url);
       else
-        u->url = url_encoded;
+        u->url = (char *) url_encoded;
     }
 
   return u;
@@ -903,7 +922,7 @@ url_parse (const char *url, int *error, struct iri *iri, bool percent_encode)
  error:
   /* Cleanup in case of error: */
   if (url_encoded && url_encoded != url)
-    xfree (url_encoded);
+    xfree ((char *) url_encoded);
 
   /* Transmit the error code to the caller, if the caller wants to
      know.  */
@@ -929,9 +948,9 @@ url_error (const char *url, int error_code)
       if ((p = strchr (scheme, ':')))
         *p = '\0';
       if (!strcasecmp (scheme, "https"))
-        asprintf (&error, _("HTTPS support not compiled in"));
+        error = aprintf (_("HTTPS support not compiled in"));
       else
-        asprintf (&error, _(parse_errors[error_code]), quote (scheme));
+        error = aprintf (_(parse_errors[error_code]), quote (scheme));
       xfree (scheme);
 
       return error;
@@ -1272,7 +1291,9 @@ enum {
   filechr_control     = 4       /* a control character, e.g. 0-31 */
 };
 
-#define FILE_CHAR_TEST(c, mask) (filechr_table[(unsigned char)(c)] & (mask))
+#define FILE_CHAR_TEST(c, mask) \
+    ((opt.restrict_files_nonascii && !c_isascii ((unsigned char)(c))) || \
+    (filechr_table[(unsigned char)(c)] & (mask)))
 
 /* Shorthands for the table: */
 #define U filechr_not_unix
@@ -1411,7 +1432,7 @@ append_uri_pathel (const char *b, const char *e, bool escaped,
         }
       assert (q - TAIL (dest) == outlen);
     }
-  
+
   /* Perform inline case transformation if required.  */
   if (opt.restrict_files_case == restrict_lowercase
       || opt.restrict_files_case == restrict_uppercase)
@@ -1425,7 +1446,7 @@ append_uri_pathel (const char *b, const char *e, bool escaped,
             *q = c_toupper (*q);
         }
     }
-          
+
   TAIL_INCR (dest, outlen);
 }
 
@@ -1486,7 +1507,7 @@ url_file_name (const struct url *u)
   /* If an alternative index file was defined, change index_filename */
   if (opt.default_page)
     index_filename = opt.default_page;
-     
+
 
   /* Start with the directory prefix, if specified. */
   if (opt.dir_prefix)
@@ -1556,11 +1577,30 @@ url_file_name (const struct url *u)
 
   if ((opt.noclobber || opt.always_rest || opt.timestamping || opt.dirstruct)
       && !(file_exists_p (fname) && !file_non_directory_p (fname)))
-    return fname;
+    {
+      unique = fname;
+    }
+  else
+    {
+      unique = unique_name (fname, true);
+      if (unique != fname)
+        xfree (fname);
+    }
+
+/* On VMS, alter the name as required. */
+#ifdef __VMS
+  {
+    char *unique2;
+
+    unique2 = ods_conform( unique);
+    if (unique2 != unique)
+      {
+        xfree (unique);
+        unique = unique2;
+      }
+  }
+#endif /* def __VMS */
 
-  unique = unique_name (fname, true);
-  if (unique != fname)
-    xfree (fname);
   return unique;
 }
 \f
@@ -1979,7 +2019,7 @@ url_string (const struct url *url, enum url_auth_mode auth_mode)
 }
 \f
 /* Return true if scheme a is similar to scheme b.
+
    Schemes are similar if they are equal.  If SSL is supported, schemes
    are also similar if one is http (SCHEME_HTTP) and the other is https
    (SCHEME_HTTPS).  */
@@ -2163,18 +2203,18 @@ test_append_uri_pathel()
     { "http://www.yoyodyne.com/path/", "somepage.html", false, "http://www.yoyodyne.com/path/somepage.html" },
   };
 
-  for (i = 0; i < sizeof(test_array)/sizeof(test_array[0]); ++i) 
+  for (i = 0; i < sizeof(test_array)/sizeof(test_array[0]); ++i)
     {
       struct growable dest;
       const char *p = test_array[i].input;
-      
+
       memset (&dest, 0, sizeof (dest));
-      
+
       append_string (test_array[i].original_url, &dest);
       append_uri_pathel (p, p + strlen(p), test_array[i].escaped, &dest);
       append_char ('\0', &dest);
 
-      mu_assert ("test_append_uri_pathel: wrong result", 
+      mu_assert ("test_append_uri_pathel: wrong result",
                  strcmp (dest.base, test_array[i].expected_result) == 0);
     }
 
@@ -2197,10 +2237,10 @@ test_are_urls_equal()
     { "http://www.adomain.com/longer-path/", "http://www.adomain.com/path/",  false },
     { "http://www.adomain.com/path%2f", "http://www.adomain.com/path/",       false },
   };
-  
-  for (i = 0; i < sizeof(test_array)/sizeof(test_array[0]); ++i) 
+
+  for (i = 0; i < sizeof(test_array)/sizeof(test_array[0]); ++i)
     {
-      mu_assert ("test_are_urls_equal: wrong result", 
+      mu_assert ("test_are_urls_equal: wrong result",
                  are_urls_equal (test_array[i].url1, test_array[i].url2) == test_array[i].expected_result);
     }