[evolution-patches] IDN patch for evolution head



Hi All,
    Attached are the patches for idnkit library, evolution-1.5, have incorporated rodo's feedback and have made the changes.

Pl. check whether these are OK.

Thanks,
Suresh
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/ChangeLog,v
retrieving revision 1.1275
diff -u -r1.1275 ChangeLog
--- ChangeLog	22 Dec 2003 16:24:16 -0000	1.1275
+++ ChangeLog	29 Dec 2003 04:12:35 -0000
@@ -1,3 +1,8 @@
+2003-12-27  Suresh Chandrasekharan <suresh chandrasekharan sun com>
+
+	* configure.in: Changes to test for idnkit library. Added
+	for International Domain Names support.
+
 2003-12-22  Rodrigo Moya <rodrigo ximian com>
 
 	* configure.in: added camel/providers/groupwise to the build.
Index: configure.in
===================================================================
RCS file: /cvs/gnome/evolution/configure.in,v
retrieving revision 1.636
diff -u -r1.636 configure.in
--- configure.in	22 Dec 2003 17:21:36 -0000	1.636
+++ configure.in	29 Dec 2003 04:12:35 -0000
@@ -312,6 +312,37 @@
 fi
 AM_CONDITIONAL(ENABLE_IPv6, test "x$enable_ipv6" = "xyes")
 
+dnl **************************************************
+dnl IDN support.
+dnl **************************************************
+
+AC_ARG_WITH(idn, 
+	[  --with-idn[=yes/no/[PREFIX]]   	enable IDN support using idnkit [default /usr/local]],
+	use_idn="$withval", use_idn="no")
+
+case "$use_idn" in
+yes)
+	if test X$prefix = XNONE ; then
+		idn_path=/usr/local
+	else
+		idn_path=$prefix
+	fi
+	;;
+no)
+	;;
+*)
+	idn_path="$use_idn"
+	;;
+esac
+
+PKG_CHECK_MODULES(IDN, idnkit, msg_idn="yes")
+AC_SUBST(IDN_LIBS)
+AC_SUBST(IDN_CFLAGS)
+
+if test "x$msg_idn" = "xyes"; then
+        AC_DEFINE(ENABLE_IDN, 1, [Enable IDN support])
+fi
+
 
 dnl **************************************************
 dnl LDAP support.
@@ -1016,7 +1047,13 @@
 AC_SUBST(E_NAME_CFLAGS)
 AC_SUBST(E_NAME_LIBS)
 
-EVO_SET_COMPILE_FLAGS(E_UTIL, gthread-2.0 gconf-2.0 libxml-2.0 libbonoboui-2.0 libglade-2.0 gal-2.2 >= $GAL_REQUIRED libgnomeui-2.0 libgnome-2.0 libgnomecanvas-2.0 $mozilla_nspr, $THREADS_CFLAGS $MANUAL_NSPR_CFLAGS, $THREADS_LIBS $MANUAL_NSPR_LIBS)
+E_UTILS_DEP=" gthread-2.0 gconf-2.0 libxml-2.0 libbonoboui-2.0 libglade-2.0 gal-2.2 >= $GAL_REQUIRED libgnomeui-2.0 libgnome-2.0 libgnomecanvas-2.0 $mozilla_nspr"
+
+if test "x$msg_idn" = "xyes"; then
+	E_UTILS_DEP="idnkit $E_UTILS_DEP"
+fi
+
+EVO_SET_COMPILE_FLAGS(E_UTIL, $E_UTILS_DEP, $THREADS_CFLAGS $MANUAL_NSPR_CFLAGS, $THREADS_LIBS $MANUAL_NSPR_LIBS)
 AC_SUBST(E_UTIL_CFLAGS)
 AC_SUBST(E_UTIL_LIBS)
 
@@ -1368,6 +1405,7 @@
 	SSL support:      $msg_ssl
 	SMIME support:    $msg_smime
 	IPv6 support:     $msg_ipv6
+	IDN support:      $msg_idn
 	Dot Locking:	  $msg_dot
 	File Locking:	  $msg_file
 	Gtk-doc:	  $enable_gtk_doc"
Index: addressbook/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/addressbook/ChangeLog,v
retrieving revision 1.1510
diff -u -r1.1510 ChangeLog
--- addressbook/ChangeLog	20 Dec 2003 01:05:11 -0000	1.1510
+++ addressbook/ChangeLog	29 Dec 2003 04:12:35 -0000
@@ -1,3 +1,27 @@
+2003-12-27  Suresh Chandrasekharan <suresh chandrasekharan sun com>
+
+	* gui/contact-editor/e-contact-editor.c: 
+
+	(fill_in_field) Convert the URL to be displayed in the contact editor
+	from ASCII Compatible Encoding (ACE) to UTF-8 encoding.
+
+	(extract_field) When setting the contact book entry use ACE encoding.
+
+	* gui/widgets/eab-contact-display.c: 
+	(on_link_clicked) Call e_uri_gnome_show_idn_url to show convert
+	non-ASCII url to ACE and show it.
+
+	(render_url) Convert the ACE encoded URL for UTF-8 url for display
+	in addressbook contact display.
+
+	* gui/component/addressbook-config.c:
+
+	(dialog_to_source) Convert the LDAP server name to ACE before 
+	saving.
+
+	(folder_page_prepare) Convert the LDAP server name to UTF-8 before
+	displaying.
+
 2003-12-19  Hans Petter Jansson  <hpj ximian com>
 
 	* gui/component/addressbook-component.c (find_first_source): Impl.
Index: addressbook/gui/component/addressbook-config.c
===================================================================
RCS file: /cvs/gnome/evolution/addressbook/gui/component/addressbook-config.c,v
retrieving revision 1.62
diff -u -r1.62 addressbook-config.c
--- addressbook/gui/component/addressbook-config.c	3 Dec 2003 15:38:32 -0000	1.62
+++ addressbook/gui/component/addressbook-config.c	29 Dec 2003 04:12:35 -0000
@@ -25,6 +25,8 @@
 
 #include <glade/glade.h>
 
+#include "e-util/e-url.h"
+
 #include "addressbook.h"
 #include "addressbook-component.h"
 #include "addressbook-config.h"
@@ -259,6 +261,9 @@
 
 	if (!strcmp ("ldap://";, e_source_group_peek_base_uri (dialog->source_group))) {
 #ifdef HAVE_LDAP
+	char *t = NULL;
+	if (dialog && dialog->host)
+		t = e_uri_encode_host ((char *) gtk_entry_get_text (GTK_ENTRY (dialog->host)));
 		e_source_set_property (source, "email_addr", gtk_entry_get_text (GTK_ENTRY (dialog->email)));
 		e_source_set_property (source, "binddn", gtk_entry_get_text (GTK_ENTRY (dialog->binddn)));
 		e_source_set_property (source, "limit", gtk_entry_get_text (GTK_ENTRY (dialog->limit_spinbutton)));
@@ -266,12 +271,13 @@
 		e_source_set_property (source, "auth", ldap_unparse_auth (dialog->auth));
 
 		str = g_strdup_printf ("%s:%s/%s?" /* trigraph prevention */ "?%s",
-				       gtk_entry_get_text (GTK_ENTRY (dialog->host)),
+					t,
 				       gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (dialog->port_combo)->entry)),
 				       gtk_entry_get_text (GTK_ENTRY (dialog->rootdn)),
 				       ldap_unparse_scope (dialog->scope));
 		e_source_set_relative_uri (source, str);
 		g_free (str);
+		g_free (t);
 #endif
 	} else {
 		const gchar *relative_uri;
@@ -957,7 +963,9 @@
 {
 	if (!dialog->display_name_changed) {
 		const char *server_name = gtk_entry_get_text (GTK_ENTRY (dialog->host));
-		gtk_entry_set_text (GTK_ENTRY (dialog->display_name), server_name);
+		char *t = e_uri_decode_host ((char*)server_name);
+		gtk_entry_set_text (GTK_ENTRY (dialog->display_name), t ? t : "");
+		 g_free (t);
 	}
 
 	gnome_druid_set_buttons_sensitive (GNOME_DRUID(dialog->druid),
Index: addressbook/gui/contact-editor/e-contact-editor.c
===================================================================
RCS file: /cvs/gnome/evolution/addressbook/gui/contact-editor/e-contact-editor.c,v
retrieving revision 1.159
diff -u -r1.159 e-contact-editor.c
--- addressbook/gui/contact-editor/e-contact-editor.c	18 Dec 2003 22:20:17 -0000	1.159
+++ addressbook/gui/contact-editor/e-contact-editor.c	29 Dec 2003 04:12:36 -0000
@@ -54,6 +54,7 @@
 #include "addressbook/printing/e-contact-print-envelope.h"
 #include "addressbook/gui/widgets/eab-gui-util.h"
 #include "e-util/e-gui-utils.h"
+#include "e-util/e-url.h"
 #include "widgets/misc/e-dateedit.h"
 #include "widgets/misc/e-url-entry.h"
 #include "widgets/misc/e-source-option-menu.h"
@@ -2361,13 +2362,19 @@
 static void
 fill_in_field(EContactEditor *editor, char *id, char *value)
 {
+	char *t = NULL;
 	GtkWidget *widget = glade_xml_get_widget(editor->gui, id);
 
 	if (!widget)
 		return;
 
-	if (E_IS_URL_ENTRY (widget))
+	if (E_IS_URL_ENTRY (widget)) {
 		widget = e_url_entry_get_entry (E_URL_ENTRY (widget));
+		if (value) {
+			t = strdup (value);
+			e_uri_replace_with_decoded_host (&t);
+		}
+	}
 
 	if (GTK_IS_TEXT_VIEW (widget)) {
 		if (value)
@@ -2378,8 +2385,10 @@
 		int position = 0;
 		GtkEditable *editable = GTK_EDITABLE(widget);
 		gtk_editable_delete_text(editable, 0, -1);
-		if (value)
-			gtk_editable_insert_text(editable, value, strlen(value), &position);
+		if (t) {
+			gtk_editable_insert_text(editable, t, strlen(t), &position);
+			g_free (t);
+		 } 
 	}
 }
 
@@ -2705,14 +2714,17 @@
 static void
 extract_field(EContactEditor *editor, EContact *contact, char *editable_id, EContactField field)
 {
+	gboolean is_url = FALSE;
 	GtkWidget *widget = glade_xml_get_widget(editor->gui, editable_id);
 	char *string = NULL;
 
 	if (!widget)
 		return;
 
-	if (E_IS_URL_ENTRY (widget))
+	if (E_IS_URL_ENTRY (widget)) {
+		is_url = TRUE;
 		widget = e_url_entry_get_entry (E_URL_ENTRY (widget));
+	}
 
 	if (GTK_IS_EDITABLE (widget))
 		string = gtk_editable_get_chars(GTK_EDITABLE (widget), 0, -1);
@@ -2727,10 +2739,13 @@
 		string = gtk_text_buffer_get_text (buffer, &start, &end, TRUE);
 	}
 
-	if (string && *string)
+	if (string && *string) {
+                if (is_url)
+                        e_uri_replace_with_encoded_host (&string);
 		e_contact_set (contact, field, string);
-	else
+	} else {
 		e_contact_set (contact, field, NULL);
+	}
 
 	if (string) g_free(string);
 }
Index: addressbook/gui/widgets/eab-contact-display.c
===================================================================
RCS file: /cvs/gnome/evolution/addressbook/gui/widgets/eab-contact-display.c,v
retrieving revision 1.2
diff -u -r1.2 eab-contact-display.c
--- addressbook/gui/widgets/eab-contact-display.c	21 Oct 2003 18:48:56 -0000	1.2
+++ addressbook/gui/widgets/eab-contact-display.c	29 Dec 2003 04:12:36 -0000
@@ -23,6 +23,7 @@
 #include "eab-contact-display.h"
 
 #include "e-util/e-html-utils.h"
+#include "e-util/e-url.h"
 #include "util/eab-destination.h"
 
 #include <string.h>
@@ -68,9 +69,9 @@
 on_link_clicked (GtkHTML *html, const char *url, EABContactDisplay *display)
 {
 	GError *err = NULL;
-		
-	gnome_url_show (url, &err);
-		
+
+        e_uri_show (url, &err);
+
 	if (err) {
 		g_warning ("gnome_url_show: %s", err->message);
 		g_error_free (err);
@@ -138,9 +139,12 @@
 	const char *str;
 	str = e_contact_get_const (contact, field);
 	if (str && *str) {
-		char *html = e_text_to_html (str, E_TEXT_TO_HTML_CONVERT_URLS);
+		char *t = strdup (str);
+		e_uri_replace_with_decoded_host (&t);
+		char *html = e_text_to_html (t, E_TEXT_TO_HTML_CONVERT_URLS);
 		gtk_html_stream_printf (html_stream, "<b>%s:</b> %s<br>",
 					html_label, html);
+		g_free (t);
 		g_free (html);
 	}
 }
Index: calendar/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/calendar/ChangeLog,v
retrieving revision 1.2031
diff -u -r1.2031 ChangeLog
--- calendar/ChangeLog	24 Dec 2003 17:39:01 -0000	1.2031
+++ calendar/ChangeLog	29 Dec 2003 04:12:36 -0000
@@ -1,3 +1,14 @@
+2003-12-28  Suresh Chandrasekharan <suresh chandrasekharan sun com>
+
+	* gui/dialogs/task-details-page.c 
+	(task_details_page_fill_widgets) Display the Web Page URL in task 
+	editor in UTF-8
+
+	* gui/e-tasks.c: (on_link_clicked) Display a link with a UTF8 hostname
+	in a browser window.
+
+	(write_html): Write the hostname of the URL in UTF8 format.
+
 2003-12-24  JP Rosevear <jpr ximian com>
 
 	* gui/e-select-names-renderer.c (esnr_start_editing): fix the
Index: calendar/gui/e-tasks.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/e-tasks.c,v
retrieving revision 1.67
diff -u -r1.67 e-tasks.c
--- calendar/gui/e-tasks.c	22 Dec 2003 15:57:23 -0000	1.67
+++ calendar/gui/e-tasks.c	29 Dec 2003 04:12:36 -0000
@@ -280,6 +280,7 @@
 	/* URL */
 	gtk_html_stream_printf (stream, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\"><B>%s</B></TD>", _("Web Page:"));
 	e_cal_component_get_url (comp, (const char **) &str);
+	e_uri_replace_with_decoded_host (&str);
 	if (str)
 		gtk_html_stream_printf (stream, "<TD><A HREF=\"%s\">%s</A></TD></TR>", str, str);
 	else
@@ -296,7 +297,7 @@
 {
         GError *err = NULL;
 
-        gnome_url_show (url, &err);
+        e_uri_show (url, &err);
 
 	if (err) {
 		g_warning ("gnome_url_show: %s", err->message);
Index: calendar/gui/dialogs/task-details-page.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/dialogs/task-details-page.c,v
retrieving revision 1.37
diff -u -r1.37 task-details-page.c
--- calendar/gui/dialogs/task-details-page.c	20 Nov 2003 15:11:40 -0000	1.37
+++ calendar/gui/dialogs/task-details-page.c	29 Dec 2003 04:12:36 -0000
@@ -32,6 +32,7 @@
 #include <widgets/misc/e-dateedit.h>
 #include <widgets/misc/e-url-entry.h>
 #include "e-util/e-dialog-widgets.h"
+#include "e-util/e-url.h"
 #include "../calendar-config.h"
 #include "../e-timezone-entry.h"
 #include "comp-editor-util.h"
@@ -285,6 +286,7 @@
 	TaskEditorPriority priority;
 	icalproperty_status status;
 	const char *url;
+	char *t = NULL;
 	struct icaltimetype *completed = NULL;
 
 	tdpage = TASK_DETAILS_PAGE (page);
@@ -359,7 +361,11 @@
 
 	/* URL */
 	e_cal_component_get_url (comp, &url);
-	e_dialog_editable_set (priv->url, url);
+
+	t = g_strdup (url);
+	e_uri_replace_with_decoded_host (&t);
+	e_dialog_editable_set (priv->url, t);
+	g_free (t);
 	
 	priv->updating = FALSE;
 }
Index: camel/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/camel/ChangeLog,v
retrieving revision 1.1945
diff -u -r1.1945 ChangeLog
--- camel/ChangeLog	24 Dec 2003 16:29:40 -0000	1.1945
+++ camel/ChangeLog	29 Dec 2003 04:12:36 -0000
@@ -1,3 +1,52 @@
+2003-12-27  Suresh Chandrasekharan <suresh chandrasekharan sun com>
+
+	* International Domain Names (IDN) support for Evolution.
+	
+	* camel-http-stream.c: (http_method_invoke) When sending a http stream
+	make sure that hostname is encoded in ACE.
+
+	* camel-url-scanner.c: (camel_url_web_end) The end of valid 
+	hostname seach is modified to include non-ASCII.
+	
+	(is_idn_domain) New function added to determine whether a 
+	non-ASCII hostname is valid.
+
+	* camel-url.h: utf8_host is added to CamelURL.
+
+	* camel-url.c: (camel_url_new_with_base) Coroesponding to each
+	host_name, store a utf8 hostname too. This will help save calls
+	to idn functions when the utf8_host is required repeatedly for a
+	utf8_host. Call to camel_url_decode is not made because 
+	e_uri_decode_host will inturn call that.
+
+	(camel_url_copy) Added  utf8_host.
+
+	* providers/imap/camel-imap-store.c: (imap_get_name) Show utf8
+	hostname in user messages.
+
+	(connect_to_server) Same as above
+
+	(imap_auth_loop) Show utf8 hostname when asking for password.
+	
+	* providers/nntp/camel-nntp-store.c: (connect_to_server) Show utf8
+	hostname in erro messages.
+
+	(nntp_store_get_name)  Show utf8  hostname in user messages.
+
+	* providers/pop3/camel-pop3-store.c: (connect_to_server): Show utf8
+	hostname in error messages.
+
+	(query_auth_types) Same
+
+	(pop3_try_authenticate) Show utf8 hostname when asking for password.
+
+	* providers/smtp/camel-smtp-transport.c: (connect_to_server) utf8
+	hostname in error messages when not able to connect.
+
+	(smtp_connect) Same
+
+	(get_name) utf8 name in status display.
+
 2003-12-24  Rodrigo Moya <rodrigo ximian com>
 
 	* providers/groupwise/camel-groupwise-provider.c
Index: camel/camel-http-stream.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/camel-http-stream.c,v
retrieving revision 1.16
diff -u -r1.16 camel-http-stream.c
--- camel/camel-http-stream.c	23 Oct 2003 19:57:58 -0000	1.16
+++ camel/camel-http-stream.c	29 Dec 2003 04:12:36 -0000
@@ -31,6 +31,8 @@
 #include <ctype.h>
 #include <errno.h>
 
+#include "e-util/e-url.h"
+
 #include "camel-http-stream.h"
 
 #include "camel-mime-utils.h"
@@ -344,6 +346,7 @@
 {
 	const char *method = NULL;
 	char *url;
+	char *t = NULL;
 	
 	switch (http->method) {
 	case CAMEL_HTTP_METHOD_GET:
@@ -357,21 +360,24 @@
 	}
 	
 	url = camel_url_to_string (http->url, 0);
+	t = e_uri_encode_host (http->url->host);
 	d(printf("HTTP Stream Sending: %s %s HTTP/1.0\r\nUser-Agent: %s\r\nHost: %s\r\n",
 		 method,
 		 http->proxy ? url : http->url->path,
-		 http->user_agent ? http->user_agent : "CamelHttpStream/1.0",
-		 http->url->host));
+		 http->user_agent ? http->user_agent : "CamelHttpStream/1.0", 
+		 t));
 	if (camel_stream_printf (http->raw, "%s %s HTTP/1.0\r\nUser-Agent: %s\r\nHost: %s\r\n",
 				 method,
 				 http->proxy ? url : http->url->path,
 				 http->user_agent ? http->user_agent : "CamelHttpStream/1.0",
-				 http->url->host) == -1) {
+				 t) == -1) {
 		http_disconnect(http);
 		g_free (url);
+		g_free (t);
 		return -1;
 	}
 	g_free (url);
+	g_free (t);
 
 	if (http->authrealm)
 		d(printf("HTTP Stream Sending: WWW-Authenticate: %s\n", http->authrealm));
Index: camel/camel-service.h
===================================================================
RCS file: /cvs/gnome/evolution/camel/camel-service.h,v
retrieving revision 1.49
diff -u -r1.49 camel-service.h
--- camel/camel-service.h	8 May 2002 21:58:37 -0000	1.49
+++ camel/camel-service.h	29 Dec 2003 04:12:36 -0000
@@ -33,6 +33,7 @@
 #pragma }
 #endif /* __cplusplus }*/
 
+#include "config.h"
 #include <netdb.h>
 #include <camel/camel-object.h>
 #include <camel/camel-url.h>
@@ -44,6 +45,14 @@
 #define CAMEL_SERVICE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_SERVICE_TYPE, CamelServiceClass))
 #define CAMEL_IS_SERVICE(o)    (CAMEL_CHECK_TYPE((o), CAMEL_SERVICE_TYPE))
 
+#ifdef ENABLE_IDN
+#define DISP_HOST(service) 	(service)->url->utf8_host ?  \
+				(service)->url->utf8_host : \
+				(service)->url->host
+#else
+#define DISP_HOST(service)	(service)->url->host
+#endif
+
 enum {
 	CAMEL_SERVICE_ARG_FIRST  = CAMEL_ARG_FIRST + 100,
 	CAMEL_SERVICE_ARG_USERNAME,
Index: camel/camel-url-scanner.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/camel-url-scanner.c,v
retrieving revision 1.6
diff -u -r1.6 camel-url-scanner.c
--- camel/camel-url-scanner.c	17 Apr 2003 16:43:06 -0000	1.6
+++ camel/camel-url-scanner.c	29 Dec 2003 04:12:37 -0000
@@ -27,6 +27,7 @@
 
 #include <string.h>
 
+#include "e-util/e-url.h"
 #include "e-util/e-trie.h"
 #include "camel-url-scanner.h"
 
@@ -36,6 +37,9 @@
 	ETrie *trie;
 };
 
+#ifdef ENABLE_IDN
+static gboolean is_idn_domain ( const char **inptr, const char *inend);
+#endif
 
 CamelUrlScanner *
 camel_url_scanner_new (void)
@@ -209,10 +213,8 @@
 				inptr++;
 			else
 				break;
-			
 			while (inptr < inend && is_domain (*inptr))
 				inptr++;
-			
 			if (inptr < inend && *inptr == '.' && is_domain (inptr[1]))
 				inptr++;
 		}
@@ -236,6 +238,7 @@
 	{ '<', '>' },
 };
 
+
 static char
 url_stop_at_brace (const char *in, size_t so)
 {
@@ -251,6 +254,31 @@
 	return '\0';
 }
 
+#ifdef ENABLE_IDN
+static gboolean
+is_idn_domain ( const char **inptr, const char *inend) {
+	char *t;
+	char inbuf[16];
+	gint len = 0;
+	
+	memset (inbuf, 0, sizeof (inbuf));
+	g_utf8_strncpy (inbuf, *inptr, 1);
+	t = e_uri_encode_host (inbuf);
+	if (t) {
+		g_free (t);
+		len = strlen (inbuf);
+		if (*inptr + len <= inend ) {
+			*inptr += len;
+			return TRUE;
+		} 
+	} else if (is_domain (**inptr)) {
+		*inptr += 1;
+		return TRUE;
+	}
+	return FALSE;
+}
+#endif
+
 gboolean
 camel_url_file_start (const char *in, const char *pos, const char *inend, urlmatch_t *match)
 {
@@ -294,7 +322,7 @@
 gboolean
 camel_url_web_end (const char *in, const char *pos, const char *inend, urlmatch_t *match)
 {
-	register const char *inptr = pos;
+	const char *inptr = pos;
 	int parts = 0, digits, port;
 	char close_brace;
 	
@@ -320,18 +348,32 @@
 				inptr++;
 			
 		} while (parts < 4);
+#ifdef ENABLE_IDN
+	} else if (is_idn_domain (&inptr, inend)) {
+#else
 	} else if (is_domain (*inptr)) {
-				while (inptr < inend) {
+#endif
+		while (inptr < inend) {
+#ifdef ENABLE_IDN
+			if (!is_idn_domain (&inptr, inend))
+				break;
+
+			while (inptr < inend && is_idn_domain (&inptr, inend));
+
+			if (inptr < inend && *inptr == '.' )
+				is_idn_domain (&(inptr)+1, inend); 
+#else
 			if (is_domain (*inptr))
 				inptr++;
 			else
 				break;
-			
+
 			while (inptr < inend && is_domain (*inptr))
 				inptr++;
-			
+
 			if (inptr < inend && *inptr == '.' && is_domain (inptr[1]))
 				inptr++;
+#endif
 		}
 	} else {
 		return FALSE;
Index: camel/camel-url.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/camel-url.c,v
retrieving revision 1.38
diff -u -r1.38 camel-url.c
--- camel/camel-url.c	9 Dec 2003 00:58:40 -0000	1.38
+++ camel/camel-url.c	29 Dec 2003 04:12:37 -0000
@@ -32,6 +32,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "e-util/e-url.h"
+
 #include "camel-url.h"
 #include "camel-exception.h"
 #include "camel-mime-utils.h"
@@ -126,10 +128,17 @@
 		colon = strchr (url_string, ':');
 		if (colon && colon < slash) {
 			url->host = g_strndup (url_string, colon - url_string);
+#ifdef ENABLE_IDN
+                        url->utf8_host = e_uri_decode_host (url->host);
+#endif
 			url->port = strtoul (colon + 1, NULL, 10);
 		} else {
 			url->host = g_strndup (url_string, slash - url_string);
-			camel_url_decode (url->host);
+#ifdef ENABLE_IDN
+                        url->utf8_host = e_uri_decode_host (url->host);
+#else			/* Don't need decoding for utf8_host */
+                        camel_url_decode (url->host);
+#endif
 			url->port = 0;
 		}
 
@@ -187,6 +196,9 @@
 	else if (base && !url->protocol) {
 		if (!url->user && !url->authmech && !url->passwd &&
 		    !url->host && !url->port && !url->path &&
+#ifdef ENABLE_IDN
+                    !url->utf8_host &&
+#endif
 		    !url->params && !url->query && !url->fragment)
 			url->fragment = g_strdup (base->fragment);
 
@@ -195,6 +207,9 @@
 		url->authmech = g_strdup (base->authmech);
 		url->passwd = g_strdup (base->passwd);
 		url->host = g_strdup (base->host);
+#ifdef ENABLE_IDN
+                url->utf8_host = g_strdup (base->utf8_host);
+#endif
 		url->port = base->port;
 
 		if (!url->path) {
Index: camel/camel-url.h
===================================================================
RCS file: /cvs/gnome/evolution/camel/camel-url.h,v
retrieving revision 1.19
diff -u -r1.19 camel-url.h
--- camel/camel-url.h	23 Apr 2003 01:34:02 -0000	1.19
+++ camel/camel-url.h	29 Dec 2003 04:12:37 -0000
@@ -42,6 +42,9 @@
 	char  *authmech;
 	char  *passwd;
 	char  *host;
+#ifdef ENABLE_IDN
+        char  *utf8_host;
+#endif
 	int    port;
 	char  *path;
 	GData *params;
Index: camel/providers/imap/camel-imap-store.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/providers/imap/camel-imap-store.c,v
retrieving revision 1.262
diff -u -r1.262 camel-imap-store.c
--- camel/providers/imap/camel-imap-store.c	10 Dec 2003 19:22:20 -0000	1.262
+++ camel/providers/imap/camel-imap-store.c	29 Dec 2003 04:12:37 -0000
@@ -456,10 +456,10 @@
 imap_get_name (CamelService *service, gboolean brief)
 {
 	if (brief)
-		return g_strdup_printf (_("IMAP server %s"), service->url->host);
+		return g_strdup_printf (_("IMAP server %s"), DISP_HOST(service));
 	else
 		return g_strdup_printf (_("IMAP service for %s on %s"),
-					service->url->user, service->url->host);
+					service->url->user, DISP_HOST(service));
 }
 
 static void
@@ -600,7 +600,8 @@
 		else
 			camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
 					      _("Could not connect to %s (port %d): %s"),
-					      service->url->host, port, g_strerror (errno));
+					      DISP_HOST(service), 
+					      port, g_strerror (errno));
 		
 		camel_object_unref (CAMEL_OBJECT (tcp_stream));
 		
@@ -663,7 +664,8 @@
 				/* server doesn't support STARTTLS, abort */
 				camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
 						      _("Failed to connect to IMAP server %s in secure mode: %s"),
-						      service->url->host, _("SSL/TLS extension not supported."));
+						      DISP_HOST(service), 
+						      _("SSL/TLS extension not supported."));
 				/* we have the possibility of quitting cleanly here */
 				clean_quit = TRUE;
 				goto exception;
@@ -694,7 +696,8 @@
 	if (camel_tcp_stream_ssl_enable_ssl (CAMEL_TCP_STREAM_SSL (tcp_stream)) == -1) {
 		camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
 				      _("Failed to connect to IMAP server %s in secure mode: %s"),
-				      service->url->host, _("SSL negotiations failed"));
+				      DISP_HOST(service), 
+				      _("SSL negotiations failed"));
 		goto exception;
 	}
 	
@@ -1246,7 +1249,7 @@
 			camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE,
 					      _("IMAP server %s does not support requested "
 						"authentication type %s"),
-					      service->url->host,
+					      DISP_HOST(service),
 					      service->url->authmech);
 			return FALSE;
 		}
@@ -1281,7 +1284,7 @@
 						    "password for %s %s"),
 						  errbuf ? errbuf : "",
 						  service->url->user,
-						  service->url->host);
+						  DISP_HOST(service));
 			service->url->passwd =
 				camel_session_get_password (session, prompt, FALSE, TRUE,
 							    service, "password", ex);
Index: camel/providers/nntp/camel-nntp-store.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/providers/nntp/camel-nntp-store.c,v
retrieving revision 1.54
diff -u -r1.54 camel-nntp-store.c
--- camel/providers/nntp/camel-nntp-store.c	22 Sep 2003 15:00:59 -0000	1.54
+++ camel/providers/nntp/camel-nntp-store.c	29 Dec 2003 04:12:37 -0000
@@ -129,7 +129,8 @@
 		else
 			camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
 					      _("Could not connect to %s (port %d): %s"),
-					      service->url->host, port, g_strerror (errno));
+	      				      DISP_HOST(service),
+					      port, g_strerror (errno));
 		
 		camel_object_unref (CAMEL_OBJECT (tcp_stream));
 		
@@ -147,7 +148,8 @@
 		else
 			camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
 					      _("Could not read greeting from %s: %s"),
-					      service->url->host, g_strerror (errno));
+	      				      DISP_HOST(service),
+					      g_strerror (errno));
 		
 		camel_object_unref (CAMEL_OBJECT (store->stream));
 		store->stream = NULL;
@@ -159,7 +161,7 @@
 	if (len != 200 && len != 201) {
 		camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
 				      _("NNTP server %s returned error code %d: %s"),
-				      service->url->host, len, buf);
+	      			      DISP_HOST(service), len, buf);
 		
 		camel_object_unref (CAMEL_OBJECT (store->stream));
 		store->stream = NULL;
@@ -255,9 +257,10 @@
 nntp_store_get_name (CamelService *service, gboolean brief)
 {
 	if (brief)
-		return g_strdup_printf ("%s", service->url->host);
+		return g_strdup_printf ("%s", DISP_HOST(service));
 	else
-		return g_strdup_printf (_("USENET News via %s"), service->url->host);
+		return g_strdup_printf (_("USENET News via %s"), 
+	      		DISP_HOST(service));
 	
 }
 
Index: camel/providers/pop3/camel-pop3-store.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/providers/pop3/camel-pop3-store.c,v
retrieving revision 1.101
diff -u -r1.101 camel-pop3-store.c
--- camel/providers/pop3/camel-pop3-store.c	28 Oct 2003 19:01:56 -0000	1.101
+++ camel/providers/pop3/camel-pop3-store.c	29 Dec 2003 04:12:37 -0000
@@ -195,7 +195,8 @@
 		else
 			camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
 					      _("Could not connect to POP server %s (port %d): %s"),
-					      service->url->host, port, g_strerror (errno));
+	      				      DISP_HOST(service),
+					      port, g_strerror (errno));
 		
 		camel_object_unref (CAMEL_OBJECT (tcp_stream));
 		
@@ -227,7 +228,8 @@
 				/* server doesn't support STARTTLS, abort */
 					camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
 							      _("Failed to connect to POP server %s in secure mode: %s"),
-							      service->url->host, _("SSL/TLS extension not supported."));
+	      						      DISP_HOST(service),
+							      _("SSL/TLS extension not supported."));
 					/* we have the possibility of quitting cleanly here */
 					clean_quit = TRUE;
 					goto stls_exception;
@@ -256,7 +258,8 @@
 	if (ret == FALSE) {
 		camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
 				      _("Failed to connect to POP server %s in secure mode: %s"),
-				      service->url->host, store->engine->line);
+	      			      DISP_HOST(service),
+				      store->engine->line);
 		goto stls_exception;
 	}
 	
@@ -268,7 +271,8 @@
 	if (ret == -1) {
 		camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
 				      _("Failed to connect to POP server %s in secure mode: %s"),
-				      service->url->host, _("SSL negotiations failed"));
+	      			      DISP_HOST(service),
+				      _("SSL negotiations failed"));
 		goto stls_exception;
 	}
 	
@@ -366,7 +370,7 @@
 	} else {
 		camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
 				      _("Could not connect to POP server %s"),
-				      service->url->host);
+	      			      DISP_HOST(service));
 	}
 
 	return types;
@@ -478,7 +482,7 @@
 		prompt = g_strdup_printf (_("%sPlease enter the POP password for %s %s"),
 					  errmsg ? errmsg : "",
 					  service->url->user,
-					  service->url->host);
+	      				  DISP_HOST(service));
 		service->url->passwd = camel_session_get_password (camel_service_get_session (service),
 								   prompt, reprompt, TRUE, service, "password", ex);
 		g_free (prompt);
Index: camel/providers/smtp/camel-smtp-transport.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/providers/smtp/camel-smtp-transport.c,v
retrieving revision 1.150
diff -u -r1.150 camel-smtp-transport.c
--- camel/providers/smtp/camel-smtp-transport.c	9 Dec 2003 00:58:46 -0000	1.150
+++ camel/providers/smtp/camel-smtp-transport.c	29 Dec 2003 04:12:37 -0000
@@ -283,7 +283,8 @@
 	if (ret == -1) {
 		camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
 				      _("Could not connect to %s (port %d): %s"),
-				      service->url->host, port,
+	      			      DISP_HOST(service),
+				      port,
 				      g_strerror (errno));
 		
 		camel_object_unref (tcp_stream);
@@ -341,7 +342,8 @@
 				/* server doesn't support STARTTLS, abort */
 				camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
 						      _("Failed to connect to SMTP server %s in secure mode: %s"),
-						      service->url->host, _("server does not appear to support SSL"));
+	      					      DISP_HOST(service),
+						      _("server does not appear to support SSL"));
 				goto exception_cleanup;
 			}
 		}
@@ -380,7 +382,8 @@
 	if (camel_tcp_stream_ssl_enable_ssl (CAMEL_TCP_STREAM_SSL (tcp_stream)) == -1) {
 		camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
 				      _("Failed to connect to SMTP server %s in secure mode: %s"),
-				      service->url->host, g_strerror (errno));
+	      			      DISP_HOST(service),
+				      g_strerror (errno));
 		goto exception_cleanup;
 	}
 	
@@ -475,7 +478,8 @@
 			camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE,
 					      _("SMTP server %s does not support requested "
 						"authentication type %s."),
-					      service->url->host, service->url->authmech);
+	      				      DISP_HOST(service),
+					      service->url->authmech);
 			camel_service_disconnect (service, TRUE, NULL);
 			return FALSE;
 		}
@@ -513,7 +517,7 @@
 				
 				prompt = g_strdup_printf (_("%sPlease enter the SMTP password for %s %s"),
 							  errbuf ? errbuf : "", service->url->user,
-							  service->url->host);
+	      						  DISP_HOST(service));
 				
 				service->url->passwd = camel_session_get_password (session, prompt, FALSE, TRUE,
 										   service, "password", ex);
@@ -663,11 +667,11 @@
 get_name (CamelService *service, gboolean brief)
 {
 	if (brief)
-		return g_strdup_printf (_("SMTP server %s"), service->url->host);
-	else {
+		return g_strdup_printf (_("SMTP server %s"), 
+	      			  DISP_HOST(service));
+	else
 		return g_strdup_printf (_("SMTP mail delivery via %s"),
-					service->url->host);
-	}
+	      			  DISP_HOST(service));
 }
 
 static gboolean
Index: e-util/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/e-util/ChangeLog,v
retrieving revision 1.427
diff -u -r1.427 ChangeLog
--- e-util/ChangeLog	6 Dec 2003 18:15:20 -0000	1.427
+++ e-util/ChangeLog	29 Dec 2003 04:12:38 -0000
@@ -1,3 +1,62 @@
+2003-12-27  Suresh Chandrasekharan <suresh chandrasekharan sun com>
+
+	* e-account.c: (xml_set_service) When setting EAccount fileds from
+	xml source, put in hostname in ASCII compatible format.
+
+	(e_account_to_xml) When writing out xmlDoc from EAccount write it
+	in ASCII compatible format. 
+
+	These two changes make sure that internal to evolution	only the
+	ASCII compatible host names are used.
+
+	* e-html-utils.c: (url_extract) Validate non-ASCII urls for 
+	making them 'clickable' display in addressbook contact display.
+
+	* e-url.c: (e_uri_new) Modified to return the right hostname part of a
+	uri, even if it does not contain a '://' part. Eg. "mailto:abc cde org"
+	now gets parsed correctly.  uri_decode function won't be called if
+	ENABLE_IDN flag is set.
+
+	(e_uri_copy) Added an additional parameter called host_offset, used
+	in replacing the original UTF-8 hostname by the ACE encoded or vice 
+	versa. 
+
+	(e_uri_to_string) Fixed the bug causing the removal of the '/' 
+	seperating the path name from the rest of url when EUri is converted 
+	back to string.
+
+	The folowing functions are added, 
+
+	(e_uri_encode_host) Pass in a UTF-8 host name and and ACE name will be
+	returned. Made robust by additional checks for encoded url etc. 
+
+	(e_uri_decode_host) Pass in an ACE host name and the equivalent UTF-8
+	hostname will be returned. This functions is made robust by additonal
+	checks and it can take in UTF-8 string, encoded url with %hex codes.
+
+	(e_uri_replace_with_decd_host) Replaces the UTF-8 hostname part of the 
+	URI with ACE encoding extra memory if need will be allocated in place.
+
+	(e_uri_replace_with_encd_host) Replaces the ACE hostname part of the 
+	URI with UTF-8 encoding extra memory if need will be allocated in place.
+
+	(e_uri_gnome_show_idn_url) Call browser with a supplied URL having 
+	UTD-8 hostname.
+
+	(replace_str) This static function is used to replace an oldstr
+	at offset oldstr_offset witha newstr, the additional memory needed
+	id allocated within.
+
+	(cache_coded_host) A functions which will store and retrieve
+	ace_name/utf8_name pairs. Used to reduce the overhead in frequent
+	idnkit function calls. Thread safe.
+
+	* e-url.h:
+	Added the parameter host_offset to EUri struct. Added 
+	e_uri_encode_host, e_uri_decode_host, e_uri_replace_with_decd_host,
+	e_uri_replace_with_encd_host and e_uri_gnome_show_idn_url
+	as new function declarations.
+
 2003-12-06  JP Rosevear <jpr ximian com>
 
 	* Makefile.am: Remove hard coded disable deprecated flags
Index: e-util/e-account.c
===================================================================
RCS file: /cvs/gnome/evolution/e-util/e-account.c,v
retrieving revision 1.5
diff -u -r1.5 e-account.c
--- e-util/e-account.c	31 Oct 2003 04:55:41 -0000	1.5
+++ e-util/e-account.c	29 Dec 2003 04:12:38 -0000
@@ -24,6 +24,7 @@
 #include "e-account.h"
 
 #include "e-uid.h"
+#include "e-url.h"
 
 #include <string.h>
 
@@ -268,7 +269,15 @@
 
 	for (node = node->children; node; node = node->next) {
 		if (!strcmp (node->name, "url")) {
-			changed |= xml_set_content (node, &service->url);
+			gboolean url_changed = FALSE;
+			url_changed = xml_set_content (node, &service->url);
+			changed |= url_changed;
+			if (url_changed && service->url) {
+				char *t = g_strdup (service->url);
+				e_uri_replace_with_encoded_host (&t);
+				g_free (service->url);
+				service->url = t;
+			} 
 			break;
 		}
 	}
@@ -478,13 +487,21 @@
 	xmlSetProp (src, "auto-check", account->source->auto_check ? "true" : "false");
 	sprintf (buf, "%d", account->source->auto_check_time);
 	xmlSetProp (src, "auto-check-timeout", buf);
-	if (account->source->url)
-		xmlNewTextChild (src, NULL, "url", account->source->url);
+	if (account->source->url) {
+		char *t = g_strdup (account->source->url);
+		e_uri_replace_with_encoded_host (&t);
+		xmlNewTextChild (src, NULL, "url", t);
+		g_free (t);
+	}
 
 	xport = xmlNewChild (root, NULL, "transport", NULL);
 	xmlSetProp (xport, "save-passwd", account->transport->save_passwd ? "true" : "false");
-	if (account->transport->url)
-		xmlNewTextChild (xport, NULL, "url", account->transport->url);
+	if (account->transport->url) {
+		char *t = g_strdup (account->transport->url);
+		e_uri_replace_with_encoded_host (&t);
+		xmlNewTextChild (xport, NULL, "url", t);
+		g_free (t);
+	}
 
 	xmlNewTextChild (root, NULL, "drafts-folder", account->drafts_folder_uri);
 	xmlNewTextChild (root, NULL, "sent-folder", account->sent_folder_uri);
Index: e-util/e-html-utils.c
===================================================================
RCS file: /cvs/gnome/evolution/e-util/e-html-utils.c,v
retrieving revision 1.40
diff -u -r1.40 e-html-utils.c
--- e-util/e-html-utils.c	7 Nov 2003 21:27:34 -0000	1.40
+++ e-util/e-html-utils.c	29 Dec 2003 04:12:38 -0000
@@ -18,11 +18,13 @@
  * Boston, MA 02111-1307, USA.
  */
 
+#include <config.h>
 #include <ctype.h>
 #include <stdio.h>
 #include <string.h>
 #include <glib.h>
 
+#include "e-url.h"
 #include "e-html-utils.h"
 
 static char *
@@ -70,7 +72,7 @@
 url_extract (const unsigned char **text, gboolean full_url)
 {
 	const unsigned char *end = *text, *p;
-	char *out;
+	char *out, *t;
 
 	while (*end && is_url_char (*end))
 		end++;
@@ -80,8 +82,32 @@
 		end--;
 
 	if (full_url) {
+#ifdef ENABLE_IDN
+		EUri *uri;
+
+		uri = e_uri_new (*text);
+		p = memchr (*text, ':', end - *text);
+		if (uri->host && (strcmp (uri->host, "") != 0)) {
+			/* if hostname OK */
+			if (p) {
+				while ((end=++p) && *end=='/');
+
+				if (*end)
+					end = (t = strchr (end,'/')) ? t : end + strlen (end);
+
+				while (*end && is_url_char (*end))
+					end++;
+
+				/* Back up if we probably went too far. */
+				while (end > *text && (special_chars [*(end - 1)] & 2))
+					end--;
+			}
+		}
+		e_uri_free (uri);
+#else
 		/* Make sure this really looks like a URL. */
 		p = memchr (*text, ':', end - *text);
+#endif
 		if (!p || end - p < 4)
 			return NULL;
 	} else {
Index: e-util/e-url.c
===================================================================
RCS file: /cvs/gnome/evolution/e-util/e-url.c,v
retrieving revision 1.11
diff -u -r1.11 e-url.c
--- e-util/e-url.c	8 May 2003 14:18:45 -0000	1.11
+++ e-util/e-url.c	29 Dec 2003 04:12:38 -0000
@@ -29,8 +29,14 @@
 #include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
+
+#ifdef ENABLE_IDN
+#include <idn/api.h>
+#endif
+
 #include "e-url.h"
 
+
 char *
 e_url_shroud (const char *url)
 {
@@ -112,8 +118,9 @@
 e_uri_new (const char *uri_string)
 {
 	EUri *uri;
-	const char *end, *hash, *colon, *semi, *at, *slash, *question;
-	const char *p;
+	const char *end, *hash, *colon, *semi, *at, *slash, *quest, *path;
+	const char *p, *uri_start = uri_string;
+	const char *host_end;
 
 	if (!uri_string)
 		return NULL;
@@ -146,65 +153,76 @@
 		return uri;
 
 	/* check for authority */
-	if (strncmp (uri_string, "//", 2) == 0) {
+	if (strncmp (uri_string, "//", 2) == 0)
 		uri_string += 2;
 
-		slash = uri_string + strcspn (uri_string, "/#");
-		at = strchr (uri_string, '@');
-		if (at && at < slash) {
-			colon = strchr (uri_string, ':');
-			if (colon && colon < at) {
-				uri->passwd = g_strndup (colon + 1, at - colon - 1);
-				uri_decode (uri->passwd);
-			}
-			else {
-				uri->passwd = NULL;
-				colon = at;
-			}
-
-			semi = strchr (uri_string, ';');
-			if (semi && semi < colon &&
-			    !strncasecmp (semi, ";auth=", 6)) {
-				uri->authmech = g_strndup (semi + 6, colon - semi - 6);
-				uri_decode (uri->authmech);
-			}
-			else {
-				uri->authmech = NULL;
-				semi = colon;
-			}
-
-			uri->user = g_strndup (uri_string, semi - uri_string);
-			uri_decode (uri->user);
-			uri_string = at + 1;
+	slash = uri_string + strcspn (uri_string, "/#");
+	at = strchr (uri_string, '@');
+	if (at && at < slash) {
+		colon = strchr (uri_string, ':');
+		if (colon && colon < at) {
+			uri->passwd = g_strndup (colon + 1, at - colon - 1);
+			uri_decode (uri->passwd);
+		}
+		else {
+			uri->passwd = NULL;
+			colon = at;
 		}
-		else
-			uri->user = uri->passwd = uri->authmech = NULL;
 
-		/* find host and port */
-		colon = strchr (uri_string, ':');
-		if (colon && colon < slash) {
-			uri->host = g_strndup (uri_string, colon - uri_string);
-			uri->port = strtoul (colon + 1, NULL, 10);
+		semi = strchr (uri_string, ';');
+		if (semi && semi < colon &&
+		    !strncasecmp (semi, ";auth=", 6)) {
+			uri->authmech = g_strndup (semi + 6, colon - semi - 6);
+			uri_decode (uri->authmech);
 		}
 		else {
-			uri->host = g_strndup (uri_string, slash - uri_string);
-			uri_decode (uri->host);
-			uri->port = 0;
+			uri->authmech = NULL;
+			semi = colon;
 		}
 
-		uri_string = slash;
+		uri->user = g_strndup (uri_string, semi - uri_string);
+		uri_decode (uri->user);
+		uri_string = at + 1;
 	}
+	else
+		uri->user = uri->passwd = uri->authmech = NULL;
 
-	/* find query */
-	question = memchr (uri_string, '?', end - uri_string);
-	if (question) {
-		if (question[1]) {
-			uri->query = g_strndup (question + 1, end - (question + 1));
-			uri_decode (uri->query);
-		}
-		end = question;
+	/* find host and port */
+	colon = strchr (uri_string, ':');
+	path = uri_string + strcspn (uri_string, "/");
+	quest = uri_string + strcspn (uri_string, "?");
+	host_end = path<quest ? path : quest;
+
+	if (colon && colon < slash) {
+		uri->host = g_strndup (uri_string, colon - uri_string);
+		uri->host_offset = uri_string - uri_start;
+#ifndef ENABLE_IDN
+		uri_decode (uri->host);
+#endif
+		uri->port = strtoul (colon + 1, (char **)&uri_string, 10);
+	}
+	else {
+		uri->host = g_strndup (uri_string, host_end - uri_string);
+		uri->host_offset = uri_string - uri_start;
+#ifndef ENABLE_IDN
+		uri_decode (uri->host);
+#endif
+		uri_string = host_end;
+		uri->port = 0;
 	}
 
+	if (path < quest && path != end && path[0] == '/' ) {
+		uri->path = g_strndup (path, quest - path);
+		uri_decode (uri->path);
+		uri_string = end;
+	} 
+
+	if (quest != end && quest[0] == '?' && quest[1]) {
+		uri->query = g_strndup (quest + 1, end - (quest + 1));
+		uri_decode (uri->query);
+		uri_string = end;
+	} 
+
 	/* find parameters */
 	semi = memchr (uri_string, ';', end - uri_string);
 	if (semi) {
@@ -266,6 +284,7 @@
 	return g_datalist_get_data (&uri->params, name);
 }
 
+
 static void
 copy_param_cb (GQuark key_id, gpointer data, gpointer user_data)
 {
@@ -274,6 +293,226 @@
 	g_datalist_id_set_data_full (&params, key_id, g_strdup (data), g_free);
 }
 
+static char *
+replace_str(char *str, int oldstr_offset, char *oldstr, char *newstr) {
+	int oldlen, newlen;
+	char *p, *q;
+
+	if (!oldstr || !newstr) {
+		return NULL;
+	}
+
+	oldlen = strlen (oldstr);
+	newlen = strlen (newstr);
+
+	if (newlen > oldlen)
+		str = (char *)realloc (str, strlen (str) + newlen - oldlen + 1);
+
+	p = str + oldstr_offset;
+
+	memmove (q = p + newlen, p + oldlen, strlen (p + oldlen) + 1);
+	memcpy (p, newstr, newlen);
+	return str;
+}
+
+static char *
+cache_coded_host (char *ace_name, char *utf8_name) {
+	static char *stored_ace = NULL;
+	static char *stored_utf8 = NULL;
+	G_LOCK_DEFINE_STATIC (cache_lock);
+
+	G_LOCK (cache_lock);
+	if (ace_name && utf8_name) {
+		if (stored_ace) g_free (stored_ace);
+		if (stored_utf8) g_free (stored_utf8);
+
+		stored_ace = g_strdup (ace_name);
+		stored_utf8 = g_strdup (utf8_name);
+		G_UNLOCK (cache_lock);
+		return NULL;
+	}
+
+	if (ace_name && !utf8_name) {
+		if (stored_utf8 && !strcmp (ace_name, stored_ace)) {
+			char *t = g_strdup (stored_utf8);
+			G_UNLOCK (cache_lock);
+			return t;
+		}
+	}
+
+	if (!ace_name && utf8_name) {
+		if (stored_ace && !strcmp (utf8_name, stored_utf8)) {
+			char *t = g_strdup (stored_ace);
+			G_UNLOCK (cache_lock);
+			return t;
+		}
+	}
+	
+	G_UNLOCK (cache_lock);
+	return NULL;
+}
+
+char *
+e_uri_decode_host (char *ace_name)
+{
+#ifndef ENABLE_IDN
+	if (ace_name) 
+		return (strdup (ace_name));
+	else	
+		return NULL;
+#else
+	idn_result_t r;
+	char utf8_name[256];
+	char *t = NULL, *d = NULL, *c = NULL;
+
+	if (!ace_name || !strcmp (ace_name,"")) {
+		return NULL;
+	}
+
+	c = t = strdup (ace_name);
+
+	uri_decode (t);	
+
+	/* make sure it is ACE */
+	for (;*c; c++) {
+		if (!isascii ((unsigned) *c)) {
+			/* Convert the whole string to ACE */
+			char *tmp = e_uri_encode_host (t);
+			g_free (t);
+			t = tmp;
+		}
+	}
+
+	if (!t && !t[0]) {
+		return  NULL;
+	}
+
+	if ((d = cache_coded_host (t, NULL)) != NULL) {
+		g_free (t);
+		return d;
+	}
+
+	r = idn_decodename ( IDN_DELIMMAP | IDN_NAMEPREP | IDN_IDNCONV | IDN_RTCHECK | IDN_ASCCHECK, t, utf8_name, sizeof (utf8_name));
+
+	if (r == idn_success) {
+		if (strcmp (t, utf8_name))
+			cache_coded_host (t, utf8_name);
+		d = strdup(utf8_name);
+	} 
+
+	g_free (t);
+
+	return d;
+#endif
+}
+
+char *
+e_uri_encode_host (char *utf8_name)
+{
+#ifndef ENABLE_IDN
+	if (utf8_name) 
+		return (strdup (utf8_name));
+	else	
+		return NULL;
+#else
+	idn_result_t r;
+	char ace_name[256];
+	char *t = NULL, *d = NULL;
+
+	
+	if (!utf8_name || !strcmp (utf8_name,"")) {
+		return NULL;
+	}
+
+	t = strdup (utf8_name);
+
+	uri_decode (t);	
+		
+	if (!t && !t[0]) {
+		return  NULL;
+	}
+
+	if ((d = cache_coded_host (NULL, t)) != NULL) {
+		g_free (t);
+		return d;
+	}
+
+	r = idn_encodename ( IDN_DELIMMAP | IDN_LOCALMAP | IDN_NAMEPREP | IDN_IDNCONV | IDN_LENCHECK | IDN_ASCCHECK, t, ace_name, sizeof (ace_name));
+
+
+	if (r == idn_success) {
+		if (strcmp (ace_name, t))
+			cache_coded_host (ace_name, t);
+		d = strdup(ace_name);
+	} 
+
+	g_free (t);
+
+	return d;
+#endif
+}
+
+void
+e_uri_show (const char *uri_string, GError **err) {
+#ifndef ENABLE_IDN
+	gnome_url_show (uri_string, err);
+#else
+	char *t = strdup (uri_string);
+
+	e_uri_replace_with_encoded_host (&t);
+	gnome_url_show (t, err);
+	g_free (t);
+#endif
+}
+
+void
+e_uri_replace_with_encoded_host (char **uri_string)
+{
+#ifndef ENABLE_IDN
+	return;
+#else
+	EUri *uri;
+	char *idnh;
+
+	
+	if (!*uri_string) return;
+
+
+	uri = e_uri_new (*uri_string);
+	if (uri->host && (strcmp (uri->host, "") != 0)) {
+		idnh =  e_uri_encode_host (uri->host);
+		if (idnh) {
+			*uri_string = replace_str (*uri_string, uri->host_offset, uri->host, idnh);
+			g_free (idnh);
+		}
+	}
+	e_uri_free (uri);
+#endif
+}
+
+void
+e_uri_replace_with_decoded_host (char **uri_string)
+{
+#ifndef ENABLE_IDN
+	return;
+#else
+	EUri *uri;
+	char *idnh;
+
+	if (!*uri_string) return;
+
+	uri = e_uri_new (*uri_string);
+	if (uri->host && (strcmp (uri->host, "") != 0)) {
+		idnh =  e_uri_decode_host (uri->host);
+		if (idnh) {
+			*uri_string = replace_str (*uri_string, uri->host_offset, uri->host, idnh);
+			g_free (idnh);
+		}
+	}
+	e_uri_free (uri);
+#endif
+}
+
 EUri *
 e_uri_copy (EUri *uri)
 {
@@ -291,6 +530,7 @@
 	uri_copy->path = g_strdup (uri->path);
 	uri_copy->query = g_strdup (uri->query);
 	uri_copy->fragment = g_strdup (uri->fragment);
+	uri_copy->host_offset = uri->host_offset;
 
 	/* copy uri->params */
 	g_datalist_foreach (&uri->params,
Index: e-util/e-url.h
===================================================================
RCS file: /cvs/gnome/evolution/e-util/e-url.h,v
retrieving revision 1.5
diff -u -r1.5 e-url.h
--- e-util/e-url.h	27 Oct 2001 16:59:34 -0000	1.5
+++ e-util/e-url.h	29 Dec 2003 04:12:38 -0000
@@ -44,6 +44,7 @@
 	GData *params;
 	char  *query;
 	char  *fragment;
+	int   host_offset;
 } EUri;
 
 EUri       *e_uri_new       (const char *uri_string);
@@ -51,6 +52,11 @@
 const char *e_uri_get_param (EUri *uri, const char *name);
 EUri       *e_uri_copy      (EUri *uri);
 char       *e_uri_to_string (EUri *uri, gboolean show_password);
+char	   *e_uri_encode_host 			(char *utf8_name);
+char	   *e_uri_decode_host 			(char *ace_name);
+void	    e_uri_replace_with_decoded_host	(char **uri_string);
+void	    e_uri_replace_with_encoded_host	(char **uri_string);
+void	    e_uri_show 				(const char *uri_string, GError **err);
 
 #endif /* __E_URL_H__ */
 
Index: mail/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/mail/ChangeLog,v
retrieving revision 1.2964
diff -u -r1.2964 ChangeLog
--- mail/ChangeLog	22 Dec 2003 14:50:56 -0000	1.2964
+++ mail/ChangeLog	29 Dec 2003 04:12:39 -0000
@@ -1,3 +1,21 @@
+2003-12-27  Suresh Chandrasekharan <suresh chandrasekharan sun com>
+	
+	* em-folder-view.c: (emfv_format_link_clicked): When a multibyte
+	hostname is appearing on a URL, convert it into suitable ASCII
+	encoding before passing over to gnome_url_show.
+
+	* mail-account-gui.c: (setup_service) Display the mail server name
+	in UTF-8 in account set up windows.
+
+	* mail-ops.c: (get_folder_desc) Change the output hostname to UTF-8.
+
+	* mail-send-recv.c: (format_url) hostname in message when the 
+	Send/receive button is clicked changed to utf8.
+
+	* mail-vfolder.c: (vfolder_adduri_desc) Display utf8 host name in
+	'Updating vfolders for uri' message
+
+
 2003-12-22  David Moore  <davmre bellsouth net>
   
   	* em-popup.c (emp_part_popup_set_background): Implemented; sets an 
Index: mail/em-folder-view.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/em-folder-view.c,v
retrieving revision 1.19
diff -u -r1.19 em-folder-view.c
--- mail/em-folder-view.c	11 Dec 2003 04:56:12 -0000	1.19
+++ mail/em-folder-view.c	29 Dec 2003 04:12:39 -0000
@@ -56,6 +56,7 @@
 
 #include "widgets/misc/e-charset-picker.h"
 
+#include <e-util/e-url.h>
 #include <e-util/e-dialog-utils.h>
 
 #include "em-format-html-display.h"
@@ -1793,9 +1794,7 @@
 		/* ignore */
 	} else {
 		GError *err = NULL;
-		
-		gnome_url_show (uri, &err);
-		
+                e_uri_show (uri, &err);
 		if (err) {
 			g_warning ("gnome_url_show: %s", err->message);
 			g_error_free (err);
Index: mail/mail-account-gui.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/mail-account-gui.c,v
retrieving revision 1.142
diff -u -r1.142 mail-account-gui.c
--- mail/mail-account-gui.c	13 Nov 2003 22:33:02 -0000	1.142
+++ mail/mail-account-gui.c	29 Dec 2003 04:12:39 -0000
@@ -35,6 +35,7 @@
 
 #include <e-util/e-account-list.h>
 #include <e-util/e-dialog-utils.h>
+#include <e-util/e-url.h>
 
 #include "em-folder-selection-button.h"
 #include "mail-account-gui.h"
@@ -1114,10 +1115,13 @@
 	if (url->host && CAMEL_PROVIDER_ALLOWS (gsvc->provider, CAMEL_URL_PART_HOST)) {
 		char *hostname;
 		
-		if (url->port)
-			hostname = g_strdup_printf ("%s:%d", url->host, url->port);
-		else
-			hostname = g_strdup (url->host);
+		if (url->port) {
+			char *h = e_uri_decode_host (url->host);
+			hostname = g_strdup_printf ("%s:%d", h, url->port);
+			g_free(h);
+		} else {
+			hostname = e_uri_decode_host (url->host);
+		}
 		
 		gtk_entry_set_text (gsvc->hostname, hostname);
 		g_free (hostname);
Index: mail/mail-send-recv.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/mail-send-recv.c,v
retrieving revision 1.79
diff -u -r1.79 mail-send-recv.c
--- mail/mail-send-recv.c	17 Nov 2003 03:32:41 -0000	1.79
+++ mail/mail-send-recv.c	29 Dec 2003 04:12:39 -0000
@@ -34,6 +34,7 @@
 #include <gtk/gtkstock.h>
 #include <libgnomeui/gnome-window-icon.h>
 
+#include "e-util/e-url.h"
 #include "e-util/e-gtk-utils.h"
 
 #include "widgets/misc/e-clipped-label.h"
@@ -250,7 +251,13 @@
 
 	url = camel_url_new(internal_url, NULL);
 	if (url->host)
-		pretty_url = g_strdup_printf(_("Server: %s, Type: %s"), url->host, url->protocol);
+		pretty_url = g_strdup_printf(_("Server: %s, Type: %s"), 
+#ifdef ENABLE_IDN
+				url->utf8_host ? url->utf8_host : url->host, 
+#else
+				url->host, 
+#endif
+				url->protocol);
 	else if (url->path)
 		pretty_url = g_strdup_printf(_("Path: %s, Type: %s"), url->path, url->protocol);
 	else 
Index: mail/mail-vfolder.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/mail-vfolder.c,v
retrieving revision 1.107
diff -u -r1.107 mail-vfolder.c
--- mail/mail-vfolder.c	3 Dec 2003 15:37:54 -0000	1.107
+++ mail/mail-vfolder.c	29 Dec 2003 04:12:39 -0000
@@ -28,6 +28,8 @@
 #include <string.h>
 #include <libgnome/gnome-i18n.h>
 
+#include <e-util/e-url.h>
+
 #include "Evolution.h"
 
 #include "mail-component.h"
@@ -201,8 +203,12 @@
 vfolder_adduri_desc(struct _mail_msg *mm, int done)
 {
 	struct _adduri_msg *m = (struct _adduri_msg *)mm;
-
-	return g_strdup_printf(_("Updating vfolders for uri: %s"), m->uri);
+	char *dup_str;
+	char *decd_uri = g_strdup (m->uri);
+	e_uri_replace_with_decoded_host (&decd_uri);
+	dup_str = g_strdup_printf(_("Updating vfolders for uri: %s"), decd_uri);
+	g_free (decd_uri);
+	return dup_str;
 }
 
 static void
Index: widgets/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/widgets/ChangeLog,v
retrieving revision 1.113
diff -u -r1.113 ChangeLog
--- widgets/ChangeLog	17 Dec 2003 00:50:03 -0000	1.113
+++ widgets/ChangeLog	29 Dec 2003 04:12:40 -0000
@@ -1,3 +1,9 @@
+2003-12-27  Suresh Chandrasekharan <suresh chandrasekharan sun com>
+
+	* misc/e-url-entry.c: (button_clicked_cb) When clicking on
+	the 'connect' button for EUrlEntry widget, change the hostname
+	to ACE before passing to gnome_url_show.
+
 2003-12-16  Hans Petter Jansson  <hpj ximian com>
 
 	* misc/e-source-option-menu.c (select_source_foreach_menu_item):
Index: widgets/misc/e-url-entry.c
===================================================================
RCS file: /cvs/gnome/evolution/widgets/misc/e-url-entry.c,v
retrieving revision 1.8
diff -u -r1.8 e-url-entry.c
--- widgets/misc/e-url-entry.c	13 Jul 2003 19:29:03 -0000	1.8
+++ widgets/misc/e-url-entry.c	29 Dec 2003 04:12:40 -0000
@@ -28,6 +28,7 @@
 #include <gtk/gtk.h>
 #include <libgnome/gnome-url.h>
 #include "e-url-entry.h"
+#include "e-util/e-url.h"
 
 struct _EUrlEntryPrivate {
 	GtkWidget *entry;
@@ -171,6 +172,8 @@
 	priv = url_entry->priv;
 	
 	url = gtk_editable_get_chars (GTK_EDITABLE (priv->entry), 0, -1);
-	gnome_url_show (url, NULL);
+
+	e_uri_show (url, NULL);
+
 	g_free (url);
 }
	International Domain Names Support in Evolution-1.5
	---------------------------------------------------

	Pre-requisite for getting IDN support in Evolution.
	---------------------------------------------------

	You need to install idnkit library.

	Download it from

	http://www.nic.ad.jp/ja/idn/idnkit/download/. 

	Apply the attached patch.IDN

	cd <idnkit_library_src>
	patch -p1 < patch.IDN

	build and install the idnkit library like


	./configure --prefix=<prefix>
	make
	make install

	Refer to libidnkit(3LIB) for documentation on supported functions.

	What's in and what's not in IDN support
	---------------------------------------
	Plainly speaking it's support for Internationalized Host Names 
	(non-ASCII) in domain name, hostname and URLs. Only host names in
	URLs come under the scope of IDN.  The path names in a URL or host
	names in e-mail addresses does not come under this.

	Internal to Evolution only ASCII Compatible Encoded host name
	corresponding to the input UTF8 is used. So this means that we
	only need to convert to UTF-8 name when we need to actually display
	the name. Due to this same same configuration files can be used by
	a IDN'ized and a non-IDN Evolution, as they are compatible and no
	8 bit characters are used.


	The following is information about IDN standards.

	The IETF IDN WG (Internationalized Domain Name Working Group) generated
	four Internet Drafts and they are now all published recently from
	the IESG as RFCs [1], [2], [3], and [4].

	The published RFCs, as a set, defines the architecture and the
	IDN support scheme called IDNA (Internationalizing Domain Names in
	Applications) [1].

	[1] RFC3490, Internationalizing Domain Names in Applications (IDNA),
	March 2003.

	ftp://ftp.ietf.org/rfc/rfc3490.txt

	[2] RFC3454, Preparation of Internationalized Strings ("stringprep"), 
	December 2002.  

	ftp://ftp.ietf.org/rfc/rfc3454.txt

	[3] RFC3491, Nameprep: A Stringprep Profile for Internationalized
	Domain Names (IDN), March 2003.

	ftp://ftp.ietf.org/rfc/rfc3491.txt

	[4] RFC3492, Punycode: A Bootstring encoding of Unicode for 
	Internationalized Domain Names in Applications (IDNA), March 2003.  
	
	ftp://ftp.ietf.org/rfc/rfc3492.txt

	The Internationalizing Domain Names in Applications [IDNA] defines and 
	suggests an implementation architecture for the IDN support in 
	Internet applications. With the IDNA implemented, the Internet 
	applications can support URIs, domain names, and host names in native 
	language in various codesets. It is specified in the IDNA that the
	URIs, domain names, and host names in various codesets should be
	converted to ACE (ASCII Compatible Encoding) at the application before
	send down to resolvers and underlying transport layers/protocols.

			     +------+
			     | User |
			     +------+
				^
				| Input and display: local interface methods
				| (pen, keyboard, glowing phosphorus, ...)
	    +-------------------|-------------------------------+
	    |                   v                               |
	    |          +-----------------------------+          |
	    |          |        Application          |          |
	    |          |  (conversion between local  |          |
	    |          |  character set and Unicode  |          |
	    |          |       is done here)         |          |
	    |          |                             |          |
	    |          |      Locale's characters    |          |
	    |          |              ^              |          |
	    |          |              |              |          |
	    |          |              v              |          |
	    |          |           Unicode           |          |
	    |          |              ^              |          |
	    |          |              |              |          |
	    |          |              v              |          |
	    |          |             ACE             |          |
	    |          +-----------------------------+          |
	    |                    ^       ^                      | End system
	    |                    |       |                      |
	    |  Call to resolver: |       | Application-specific |
	    |               ACE  |       | protocol:            |
	    |                    v       | predefined by the    |
	    |           +----------+     | protocol or defaults |
	    |           | Resolver |     | to ACE               |
	    |           +----------+     |                      |
	    |                 ^          |                      |
	    +-----------------|----------|----------------------+
		DNS protocol: |          |
			  ACE |          |
			      v          v
		   +-------------+    +---------------------+
		   | DNS servers |    | Application servers |
		   +-------------+    +---------------------+	

	In Evolution since UTF-8 is used as the internal codeset the 
	conversion step between current locale's codeset and UTF-8 avoided.

	IDN support currently not covers host name part of e-mail addresses
	as there are conflicting standards proposed,  Internationalized
	Resource Identifiers is being standardized at W3C/IETF and the
	Internationalizing Mail Addresses in Applications is being
	std'zed at IETF, and there is an infra change proposal to support
	internationalized email address.  The following are the links to the
	above three.	

	http://www.ietf.org/internet-drafts/draft-hoffman-imaa-03.txt
	http://www.ietf.org/internet-drafts/draft-klensin-emailaddr-i18n-01.txt
	http://www.ietf.org/internet-drafts/draft-duerst-iri-05.txt 

	seems like these conflicting proposed standards will take 1-2 years for
	reaching consensus, for the time being e-mail addresses are not 
	covered under IDN.


	Whats IDN support in Evolution mean to the end user.
	---------------------------------------------------

		With IDN supported evolution we can configure a non-ASCII host
	name as the name for the mail server or calendar sever or LDAP server
	in evolution.  Also urls with non-ASCII host names can be clicked
	to reach the web pages. Also we can configure non-ASCII host names
	in the urls of the addressbook used by the contacts etc. Basically
	in all places a domain name, host name is used, it can be substituted
	by it's non-ASCII version.

	One thing to notice that, the path name part of the URL is still 
	confined to ASCII characters. Only the host name part can be non-ASCII.

	The configuration files and data files produced by a IDN'ized version
	of evolution is fully readable by a version which's not IDN'ized. What
	this means is only for display purposes to the end user the non-ASCII
	names are used, internally evolution uses ASCII Compatible Encoded
	(ACE) host names for library/system calls interface. This makes sharing
	of the address book etc. possible by apps which is not IDN'ized with
	IDN supported evolution.


	How to create aliases for hostnames.
	------------------------------------

	If you do have a mail server/LDAP server/calendar server which you
	want to try this on, log in to a UTF-8 locale, Add the <idn_prefix>/bin
	directory to your path if it's not already in, pick a UTF8 name you
	want to be the host name. Then

	utf2ace <UTF8-hostname>

	It will output a ASCII name staring with 'xn--', like xn--48jm8lu34qkgo
	Here utf2ace binary is distributed as a part of idnkit library.
	Ask your sys admin to create an alias for your server with this
	ASCII name, so that

	ypmatch <original hostname> hosts

	return the xn--48jm8lu34qkgo name too. After that xn--48jm8lu34qkgo
	that name in in the Evoution Settings. After you save it it will be
	displayed as the UTF8 name and in all messages password dialog etc.
	the UTF8 name will be used.

	Building Evolution
	-------------------

	Use '--with-idn=<idn prefix>' flag for enabling idn support when
	configuring evolution.
diff -Naur idnkit-1.0-src/ChangeLog idnkit-1.0-src.new/ChangeLog
--- idnkit-1.0-src/ChangeLog	2003-03-16 19:51:33.000000000 -0800
+++ idnkit-1.0-src.new/ChangeLog	2003-12-24 12:24:32.000000000 -0800
@@ -1,3 +1,25 @@
+2003-12-24 suresh chandrasekharan sun com <suresh chandrasekharan sun com>
+
+	* tools/idnconv/utf2ace.c: creates a a simple utility, which will
+	validate input UTF-8 names  and will cretate corresponding ACE
+	names if the UTF-8 name is good for being a hostname.
+
+	* tools/idnconv/Makefile.in: Makefile.in changes for utf2ace. 
+
+2003-11-11 suresh chandrasekharan sun com <suresh chandrasekharan sun com>
+
+	Patched the following 3 files from patches created by Ienup Sung.
+
+	* lib/aliaslist.c: (idn__aliaslist_aliasfile), additional check
+	for preventing buffer overflow.
+		
+	* lib/ucs4.c: (idn_ucs4_utf8toucs4) first_byte value based check for
+	invalid character.
+
+	* lib/utf8.c: (idn_utf8_getmb) Check for invalid utf-8 bytes added.
+	(idn_utf8_getwc)  Check for invalid utf-8 bytes added.	
+	(idn_utf8_findfirstbyte) Check for invalid utf-8 bytes added.
+
 2003-03-16
 	* idnkit 1.0 release.
 
diff -Naur idnkit-1.0-src/DISTFILES idnkit-1.0-src.new/DISTFILES
--- idnkit-1.0-src/DISTFILES	2003-03-16 19:51:33.000000000 -0800
+++ idnkit-1.0-src.new/DISTFILES	2003-12-24 12:26:48.000000000 -0800
@@ -17,6 +17,7 @@
 ltmain.sh
 configure.in
 configure
+idnkit.pc.in
 install-sh
 mkinstalldirs
 include/Makefile.in
@@ -136,6 +137,7 @@
 tools/idnconv/idnconv.c
 tools/idnconv/selectiveencode.c
 tools/idnconv/selectiveencode.h
+tools/idnconv/utf2ace.c
 tools/idnconv/util.c
 tools/idnconv/util.h
 tools/idnconv/idnconv.1
diff -Naur idnkit-1.0-src/Makefile.in idnkit-1.0-src.new/Makefile.in
--- idnkit-1.0-src/Makefile.in	2003-03-12 08:14:41.000000000 -0800
+++ idnkit-1.0-src.new/Makefile.in	2003-12-24 12:24:32.000000000 -0800
@@ -40,25 +40,36 @@
 #    ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 
 srcdir = @srcdir@
+top_srcdir = @top_srcdir@
 VPATH = @srcdir@
 
 prefix = @prefix@
+libdir = @libdir@
+
 exec_prefix = @exec_prefix@
 
 PERL = perl
 MKTARPKG = ../util/mktarpkg
 SHELL = @SHELL@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 
 SUBDIRS = include lib man tools map
 
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = idnkit.pc
+
+EXTRA_DIST = idnkit.pc.in
+
 all: force all-subdirs
 test check: force test-subdirs
-install: force install-subdirs
-clean: force clean-subdirs
+install: install-pkgconfigDATA force install-subdirs 
+clean: force clean-subdirs $(pkgconfig_DATA)
 distclean: force distclean-localdir distclean-subdirs
 
 distclean-localdir:
-	rm -f config.status config.cache config.log libtool Makefile
+	rm -f config.status config.cache config.log libtool Makefile idnkit.pc
 
 all-subdirs install-subdirs clean-subdirs distclean-subdirs test-subdirs:
 	@target=`echo $@ | sed 's/-subdirs$$//'`; \
@@ -66,6 +77,25 @@
 	    (cd $$d; $(MAKE) DESTDIR=$(DESTDIR) $$target); \
 	done
 
+pkgconfigDATA_INSTALL = $(INSTALL_DATA)
+install-pkgconfigDATA: $(pkgconfig_DATA)
+	@$(NORMAL_INSTALL)
+	$(mkinstalldirs) $(DESTDIR)$(pkgconfigdir)
+	@list='$(pkgconfig_DATA)'; for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  f="`echo $$p | sed -e 's|^.*/||'`"; \
+	  echo " $(pkgconfigDATA_INSTALL) $$d$$p $(DESTDIR)$(pkgconfigdir)/$$f"; \
+	  $(pkgconfigDATA_INSTALL) $$d$$p $(DESTDIR)$(pkgconfigdir)/$$f; \
+	done
+
+uninstall-pkgconfigDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(pkgconfig_DATA)'; for p in $$list; do \
+	  f="`echo $$p | sed -e 's|^.*/||'`"; \
+	  echo " rm -f $(DESTDIR)$(pkgconfigdir)/$$f"; \
+	  rm -f $(DESTDIR)$(pkgconfigdir)/$$f; \
+	done
+
 install-config:
 	(cd lib; $(MAKE) install-config);
 
diff -Naur idnkit-1.0-src/configure idnkit-1.0-src.new/configure
--- idnkit-1.0-src/configure	2003-03-10 15:53:20.000000000 -0800
+++ idnkit-1.0-src.new/configure	2003-12-24 12:25:26.000000000 -0800
@@ -3208,6 +3208,7 @@
 ac_given_INSTALL="$INSTALL"
 
 trap 'rm -fr `echo "Makefile
+	idnkit.pc
 	include/Makefile
 	include/idn/Makefile
 	include/mdn/Makefile
@@ -3326,6 +3327,7 @@
 cat >> $CONFIG_STATUS <<EOF
 
 CONFIG_FILES=\${CONFIG_FILES-"Makefile
+	idnkit.pc
 	include/Makefile
 	include/idn/Makefile
 	include/mdn/Makefile
diff -Naur idnkit-1.0-src/configure.in idnkit-1.0-src.new/configure.in
--- idnkit-1.0-src/configure.in	2003-03-10 15:53:20.000000000 -0800
+++ idnkit-1.0-src.new/configure.in	2003-12-24 12:25:00.000000000 -0800
@@ -697,6 +697,7 @@
 AC_CONFIG_HEADER(include/config.h)
 AC_OUTPUT(
 	Makefile
+	idnkit.pc
 	include/Makefile
 	include/idn/Makefile
 	include/mdn/Makefile
diff -Naur idnkit-1.0-src/idnkit.pc.in idnkit-1.0-src.new/idnkit.pc.in
--- idnkit-1.0-src/idnkit.pc.in	1969-12-31 16:00:00.000000000 -0800
+++ idnkit-1.0-src.new/idnkit.pc.in	2003-12-24 12:24:32.000000000 -0800
@@ -0,0 +1,11 @@
+prefix= prefix@
+exec_prefix= exec_prefix@
+libdir= libdir@
+includedir= includedir@
+                                                                                
+Name: idnkit
+Version: 1
+Description: International Domain Names library and development files.
+                                                                                
+Libs: -L${libdir} -lidnkit
+Cflags: -I${includedir}/
diff -Naur idnkit-1.0-src/lib/aliaslist.c idnkit-1.0-src.new/lib/aliaslist.c
--- idnkit-1.0-src/lib/aliaslist.c	2002-11-29 06:26:53.000000000 -0800
+++ idnkit-1.0-src.new/lib/aliaslist.c	2003-12-24 12:24:32.000000000 -0800
@@ -142,10 +142,11 @@
 	for (line_no = 1; fgets(line, sizeof(line), fp) != NULL; line_no++) {
 		unsigned char *p = (unsigned char *)line;
 
-		while (isascii(*p) && isspace(*p))
+		while (*p != '\n' && *p != '\0' && isascii(*p) && isspace(*p))
 			p++;
-		if (*p == '#' || *p == '\n')
+		if (*p == '#' || *p == '\n' || *p == '\0')
 			continue;
+
 		if (sscanf((char *)p, "%s %s", alias, real) == 2) {
 			r = additem_to_bottom(list, alias, real);
 			if (r != idn_success)
diff -Naur idnkit-1.0-src/lib/ucs4.c idnkit-1.0-src.new/lib/ucs4.c
--- idnkit-1.0-src/lib/ucs4.c	2002-11-29 06:26:54.000000000 -0800
+++ idnkit-1.0-src.new/lib/ucs4.c	2003-12-24 12:24:32.000000000 -0800
@@ -200,6 +200,7 @@
 	unsigned long *ucs4p = ucs4;
 	unsigned long v, min;
 	unsigned char c;
+	unsigned char first_byte;
 	int width;
 	int i;
 	idn_result_t r;
@@ -243,15 +244,21 @@
 			goto ret;
 		}
 
+		first_byte = c;
 		for (i = width - 1; i > 0; i--) {
 			c = *utf8p++;
-			if (c < 0x80 || 0xc0 <= c) {
+			if ((first_byte == 0xe0 && c < 0xa0) ||
+			    (first_byte == 0xed && c > 0x9f) ||
+			    (first_byte == 0xf0 && c < 0x90) ||
+			    (first_byte == 0xf4 && c > 0x8f) ||
+			    c < 0x80 || 0xc0 <= c) {
 				WARNING(("idn_ucs4_utf8toucs4: "
 					 "invalid character\n"));
 				r = idn_invalid_encoding;
 				goto ret;
 			}
 			v = (v << 6) | (c & 0x3f);
+			first_byte = 0;
 		}
 
 	        if (v < min) {
diff -Naur idnkit-1.0-src/lib/utf8.c idnkit-1.0-src.new/lib/utf8.c
--- idnkit-1.0-src/lib/utf8.c	2002-11-29 06:26:55.000000000 -0800
+++ idnkit-1.0-src.new/lib/utf8.c	2003-12-24 12:24:32.000000000 -0800
@@ -64,6 +64,14 @@
 
 #define VALID_CONT_BYTE(c)	(0x80 <= (c) && (c) < 0xc0)
 
+#define	INVALID_CONT_BYTE(first_byte, next_byte) \
+	(((first_byte) == 0xe0 && (next_byte) < 0xa0) || \
+	 ((first_byte) == 0xed && (next_byte) > 0x9f) || \
+	 ((first_byte) == 0xf0 && (next_byte) < 0x90) || \
+	 ((first_byte) == 0xf4 && (next_byte) > 0x8f) || \
+	 (next_byte) < 0x80 || \
+	 (next_byte) > 0xbf)
+
 int
 idn_utf8_mblen(const char *s) {
 	int c = *(unsigned char *)s;
@@ -82,6 +90,7 @@
 	/* buf must be at least 7-bytes long */
 	const unsigned char *p = (const unsigned char *)s;
 	unsigned char *q = (unsigned char *)buf;
+	unsigned char first_byte;
 	int width = UTF8_WIDTH(*p);
 	int w;
 
@@ -96,14 +105,15 @@
 		return (0);
 
 	/* Copy the first byte. */
-	*q++ = *p++;
+	first_byte = *q++ = *p++;
 
 	/* .. and the rest. */
 	w = width;
 	while (--w > 0) {
-		if (!VALID_CONT_BYTE(*p))
+		if (INVALID_CONT_BYTE(first_byte, (*p)))
 			return (0);
 		*q++ = *p++;
+		first_byte = '\0';
 	}
 	return (width);
 }
@@ -113,7 +123,7 @@
 	unsigned long v;
 	unsigned long min;
 	const unsigned char *p = (const unsigned char *)s;
-	int c;
+	unsigned long c;
 	int width;
 	int rest;
 
@@ -164,7 +174,7 @@
 		
 	rest = width - 1;
 	while (rest-- > 0) {
-		if (!VALID_CONT_BYTE(*p))
+		if (INVALID_CONT_BYTE(c, (*p)))
 			return (0);
 		v = (v << 6) | (*p & 0x3f);
 		p++;
@@ -269,7 +279,9 @@
 		    break;
 		p--;
 	}
-	if (p < t || UTF8_WIDTH(*p) == 0)
+	if (p < t || UTF8_WIDTH(*p) == 0 ||
+	    (UTF8_WIDTH(*p) >= 2 && (const unsigned char *)s > p &&
+	     INVALID_CONT_BYTE((*p), (*(p + 1)))))
 		return (NULL);
 
 	return ((char *)p);
diff -Naur idnkit-1.0-src/tools/idnconv/Makefile.in idnkit-1.0-src.new/tools/idnconv/Makefile.in
--- idnkit-1.0-src/tools/idnconv/Makefile.in	2002-11-29 06:26:57.000000000 -0800
+++ idnkit-1.0-src.new/tools/idnconv/Makefile.in	2003-12-24 12:24:32.000000000 -0800
@@ -71,11 +71,12 @@
 CFLAGS = $(INCS) $(DEFS) @CPPFLAGS@ @CFLAGS@
 LDFLAGS = @LDFLAGS@
 
-SRCS = idnconv.c util.c selectiveencode.c
-OBJS = idnconv.o util.o selectiveencode.o
+SRCS = idnconv.c util.c selectiveencode.c utf2ace.c
+OBJS = idnconv.o util.o selectiveencode.o 
+UTF2ACE_OBJ = utf2ace.o
 
 @LITEONLY_TRUE all:
- LITEONLY_FALSE@all: idnconv idnslookup idnconv.1
+ LITEONLY_FALSE@all: idnconv idnslookup utf2ace idnconv.1
 
 idnconv: $(OBJS) $(IDNLIB)
 	$(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -o $@ \
@@ -85,6 +86,10 @@
 	sed -e 's%[ ]bindir[@]%$(bindir)%' $(srcdir)/idnslookup.in > idnslookup
 	chmod 0755 idnslookup
 
+utf2ace: $(UTF2ACE_OBJ) $(IDNLIB)
+	$(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -o $@ \
+		$(UTF2ACE_OBJ) $(IDNLIB)
+
 @LITEONLY_TRUE install:
 @LITEONLY_FALSE@@COMPAT_TRUE install: all install-nolite install-compat
 @LITEONLY_FALSE@@COMPAT_FALSE install: all install-nolite
@@ -93,6 +98,8 @@
 	$(MKINSTALLDIRS) $(DESTDIR)$(bindir)
 	$(LIBTOOL) --mode=install $(INSTALL_PROGRAM) idnconv \
 	    $(DESTDIR)$(bindir)/idnconv
+	$(LIBTOOL) --mode=install $(INSTALL_PROGRAM) utf2ace \
+	    $(DESTDIR)$(bindir)/utf2ace
 	$(MKINSTALLDIRS) $(DESTDIR)$(man1dir)
 	$(INSTALL_DATA) $(srcdir)/idnconv.1 $(DESTDIR)$(man1dir)/idnconv.1
 
@@ -107,7 +114,7 @@
 	ln $$src $$dst || cp $$src $$dst
 
 clean:
-	rm -f *.o idnconv idnslookup *.core core *~
+	rm -f *.o idnconv idnslookup utf2ace core core *~
 	rm -fr .libs/
 
 distclean: clean
diff -Naur idnkit-1.0-src/tools/idnconv/utf2ace.c idnkit-1.0-src.new/tools/idnconv/utf2ace.c
--- idnkit-1.0-src/tools/idnconv/utf2ace.c	1969-12-31 16:00:00.000000000 -0800
+++ idnkit-1.0-src.new/tools/idnconv/utf2ace.c	2003-12-24 12:24:32.000000000 -0800
@@ -0,0 +1,36 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <idn/api.h>
+
+int main(int argc, char *argv[]) {
+		idn_result_t r;
+		char ace_name[256];
+		char changed_name[256];
+		int i = 1;
+
+		if ( argc<2 ) {
+			printf ("Usage: %s \"UTF-8 hostname\"\n",argv[0]);
+			exit (-1);
+		}
+	
+		do {
+			r =  idn_encodename (IDN_DELIMMAP | IDN_LOCALMAP | IDN_NAMEPREP | IDN_IDNCONV | IDN_LENCHECK | IDN_ASCCHECK, argv[i], ace_name, sizeof (ace_name));
+
+			if (r != idn_success) {
+				fprintf (stderr, "idn_encodename failed: \n");
+				continue;
+			}
+
+			r = idn_decodename(IDN_DELIMMAP | IDN_NAMEPREP | IDN_IDNCONV | IDN_RTCHECK | IDN_ASCCHECK, ace_name, changed_name, sizeof (changed_name)); 
+
+			if (r != idn_success) {
+				fprintf (stderr, "idn_decodename failed: \n");
+				continue;
+			}
+
+			printf("%s -----> %s\n", argv[i], ace_name);
+
+		} while (++i < argc);
+
+		return 0;
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]