]> sjero.net Git - wget/blobdiff - src/iri.c
Basic IDN/IRI support
[wget] / src / iri.c
index 000f655037eeafb222d8078302551cee707104d1..32eb7210fdea7d2cbca2d8ab2414510611404c79 100644 (file)
--- a/src/iri.c
+++ b/src/iri.c
@@ -41,6 +41,8 @@ as that of the covered work.  */
 #include "utils.h"
 #include "iri.h"
 
+char *remote;
+char *current;
 
 static iconv_t locale2utf8;
 
@@ -80,7 +82,7 @@ parse_charset (char *str)
       return NULL;
     }
 
-  logprintf (LOG_VERBOSE, "parse_charset: %s\n", quote (charset));
+  /*logprintf (LOG_VERBOSE, "parse_charset: %s\n", quote (charset));*/
 
   return charset;
 }
@@ -196,7 +198,7 @@ do_conversion (iconv_t cd, char *in, size_t inlen, char **out)
           (*out)++;
           outlen--;
         }
-      else if (errno == E2BIG) /* Output buffer full */ 
+      else if (errno == E2BIG) /* Output buffer full */
         {
           char *new;
 
@@ -222,15 +224,29 @@ do_conversion (iconv_t cd, char *in, size_t inlen, char **out)
 
 /* Try to ASCII encode UTF-8 host. Return the new domain on success or NULL
    on error. */
-char *idn_encode (char *host)
+char *
+idn_encode (char *host, bool utf8_encoded)
 {
   char *new;
   int ret;
 
+  /* Encode to UTF-8 if not done using current remote */
+  if (!utf8_encoded)
+    {
+      if (!remote_to_utf8 ((const char *) host, (const char **) &new))
+        {
+          /* Nothing to encode or an error occured */
+          return NULL;
+        }
+
+      host = new;
+    }
+
   /* toASCII UTF-8 NULL terminated string */
   ret = idna_to_ascii_8z (host, &new, 0);
   if (ret != IDNA_SUCCESS)
     {
+      /* sXXXav : free new when needed ! */
       logprintf (LOG_VERBOSE, "idn_encode failed (%d): %s\n", ret,
                  quote (idna_strerror (ret)));
       return NULL;
@@ -241,7 +257,8 @@ char *idn_encode (char *host)
 
 /* Try to decode an ASCII encoded host. Return the new domain in the locale on
    success or NULL on error. */
-char *idn_decode (char *host)
+char *
+idn_decode (char *host)
 {
   char *new;
   int ret;
@@ -257,4 +274,87 @@ char *idn_decode (char *host)
   return new;
 }
 
+/* Return a new string */
+bool
+remote_to_utf8 (const char *str, const char **new)
+{
+  char *remote;
+  iconv_t cd;
+  bool ret = false;
+
+  if (opt.encoding_remote)
+    remote = opt.encoding_remote;
+  else if (current)
+    remote = current;
+  else
+    return false;
+
+  cd = iconv_open ("UTF-8", remote);
+  if (cd == (iconv_t)(-1))
+    return false;
+
+  if (do_conversion (cd, (char *) str, strlen ((char *) str), (char **) new))
+    ret = true;
+
+  iconv_close (cd);
+
+  /* Test if something was converted */
+  if (!strcmp (str, *new))
+    {
+      xfree ((char *) *new);
+      return false;
+    }
+
+  return ret;
+}
+
+char *get_remote_charset (void)
+{
+  return remote;
+}
+
+char *get_current_charset (void)
+{
+  return current;
+}
+
+void set_current_charset (char *charset)
+{
+  /*printf("[ current = `%s'\n", charset);*/
+
+  if (current)
+    xfree (current);
+
+  current = charset ? xstrdup (charset) : NULL;
+}
+
+void set_current_as_locale (void)
+{
+  /*printf("[ current = locale = `%s'\n", opt.locale);*/
+  if (current)
+    xfree (current);
+
+  /* sXXXav : assert opt.locale NULL ? */
+  current = xstrdup (opt.locale);
+}
+
+void
+set_remote_charset (char *charset)
+{
+  /*printf("[ remote = `%s'\n", charset);*/
+  if (remote)
+    xfree (remote);
+
+  remote = charset ? xstrdup (charset) : NULL;
+}
+
+void
+set_remote_as_current (void)
+{
+  /*printf("[ remote = current = `%s'\n", current);*/
+  if (remote)
+    xfree (remote);
+
+  remote = current ? xstrdup (current) : NULL;
+}