diff -pru dillo/src/IO/Url.c new/cvs/dillo.new/src/IO/Url.c
--- dillo/src/IO/Url.c	Wed Mar  7 16:38:13 2001
+++ new/cvs/dillo.new/src/IO/Url.c	Mon Mar  5 02:56:20 2001
@@ -16,6 +16,7 @@
  * Two types of functions here:
  *     1.- URL handling for openning URLs
  *     2.- URL parsing (as strings)
+ *         LBS: ^^^^^^  these have been moved to ../urlparse.[ch]
  */
 
 
@@ -34,7 +35,8 @@ typedef struct {
 /*
  * Local data
  */
-char *HTTP_Proxy = NULL, *No_Proxy = NULL;
+DilloURL *HTTP_Proxy = NULL;
+char *No_Proxy = NULL;
 
 static gint UrlOpenersSize = 0, UrlOpenersMax = 8;
 static __Open_t *UrlOpeners = NULL;
@@ -46,7 +48,7 @@ static UrlMethod_t *UrlMethods = NULL;
  * Forward declarations
  */
 gint Url_add_opener(__Open_t F);
-gint Url_open(const char *url, void *Data);
+gint Url_open(const DilloURL *url, void *Data);
 
 /*
  * Add a method for Url handling
@@ -65,51 +67,40 @@ gint Url_add_method(const char *Name, __
  * Searches the Url methods list and returns the matching one
  * (UrlMethods list is not the UrlOpeners list. Don't be confused)
  */
-__Open_t Url_proto_fetch(const char *Key, gint Size)
+__Open_t Url_proto_fetch(const char *Key)
 {
    gint i, j;
 
    for ( i = 0; i < UrlMethodsSize; ++i ) {
-      for ( j = 0; j < Size; ++j )
+      for ( j = 0; Key[j]; ++j )
          if ( tolower(Key[j]) != tolower(UrlMethods[i].Name[j]) )
             break;
-      if ( j == Size )
+      if ( !Key[j] )
          return UrlMethods[i].Data;
    }
    return NULL;
 }
 
 /*
- * This identifies the method specified in the URL.
- * On success, Method is set to point the start of the method string; it is
- * NOT a zero terminated string.
- *
- * Return Value:
- *   < 1 on error, otherwise the length of the method string.
- */
-gint Url_proto_parse(const char *URL, const char **Method)
-{
-
-   char *EPtr = strpbrk(URL, URN_OTHER);
-
-   if (!EPtr || *EPtr != ':')
-      return 0;
-   *Method = URL;
-
-   return (EPtr - URL);
-}
-
-/*
  * Sets the handler methods for the different protocols supported by Dillo
  */
 gint a_Url_init(void)
 {
-   HTTP_Proxy = getenv("http_proxy");
+   char *env_http_proxy;
+
+   env_http_proxy = getenv("http_proxy");
    No_Proxy = getenv("no_proxy");
-   if (!HTTP_Proxy && prefs.http_proxy)
-      HTTP_Proxy = prefs.http_proxy;
+
+   if (!env_http_proxy && prefs.http_proxy)
+      env_http_proxy = prefs.http_proxy;
+   if (env_http_proxy) {
+      HTTP_Proxy = a_string_to_Url(env_http_proxy);
+      g_free(env_http_proxy);
+   }
+
    if (!No_Proxy && prefs.no_proxy)
       No_Proxy = prefs.no_proxy;
+
    if (Url_add_opener(a_Proto_get_url) ||
        Url_add_opener(Url_open) ||
        Url_add_method("file", a_File_get) ||
@@ -145,20 +136,19 @@ gint Url_add_opener(__Open_t F)
  * Return Value:
  *   < 0 on error, otherwise the file descriptor to get the data from
  */
-gint Url_open(const char *url, void *Data)
+gint Url_open(const DilloURL *url, void *Data)
 {
    const char *Method;
-   gint Length;
    __Open_t MPtr;
 
    /* Use the method to figure out what to do */
-   Method = NULL;
-   Length = Url_proto_parse(url, &Method);
-   if ( Length < 1 )
+   Method = a_Url_get_protocol(url);
+
+   if (! Method)
       return -1;
 
    /* Scan our method tree to see if there is anything. */
-   if (!(MPtr = Url_proto_fetch(Method, Length)))
+   if (!(MPtr = Url_proto_fetch(Method)))
       return -1;
    return MPtr(url, Data);
 }
@@ -172,7 +162,7 @@ gint Url_open(const char *url, void *Dat
  * Side effect:
  *   The file descriptor is set to background IO
  */
-gint a_Url_open(const char *Url, void *Data)
+gint a_Url_open(const DilloURL *Url, void *Data)
 {
    gint i, FD;
 
@@ -185,249 +175,3 @@ gint a_Url_open(const char *Url, void *D
    }
    return -1;
 }
-
-
-/*
- * URL parsing routines ====================================================
- */
-
-/*
- * This routine checks to see if the URL passed is of the absolute form, or
- * of the relative form
- *
- * Return Value:
- *   0 is not absolute, otherwise is absolute
- */
-gint a_Url_is_absolute(const char *url)
-{
-   const char *P = strpbrk(url, URN_OTHER);
-
-   return (P && *P == ':');
-}
-
-/*
- * Parse "http://a/b#c" into "http://a/b" and "#c".
- *
- * Return Value:
- *   a pointer to the last hash (if any), otherwise NULL.
- */
-char* a_Url_parse_hash(const char *Url)
-{
-   /* todo: I haven't checked this for standards compliance. What's it
-    * supposed to do when there are two hashes? */
-   /* Just use the last #c --MR-- */
-
-   return strrchr(Url, '#');
-}
-
-/*
- * Return TRUE if the method matches.
- */
-static gint Url_match_method(const char *url, const char *method,
-                            size_t Method_Size)
-{
-   if (g_strncasecmp(url, method, Method_Size))
-      return 0;
-   return (url[Method_Size] == ':');
-}
-
-/*
- * Squeeze an URL (strip /./ and /../ sequences)
- * Return value: squeezed URL.
- *  The funny thing is that I don't know if this is required!
- *  Anyway, it's highly tuned for speed  --Jcid
- */
-char *a_Url_squeeze(char *str)
-{
-   char *s, *p;
-   int i, ni, nc;
-
-   s = p = str;
-   ni = 0;
-   while ( (p = strstr(p, "/.")) != NULL ) {
-      if ( p[2] == '.' && (p[3] == '/' || !p[3]) ) { /* "/../" or "/.." */
-         nc = p - s;
-         for ( i = 0; i <= nc; ++i, ++ni )
-            str[ni] = s[i];
-         nc = ni > 0 ? --ni : ni;
-         while ( ni && str[--ni] != '/' );
-         if (!ni || (ni == 6 && !strncmp(str, "http://",7)) )
-           ni = nc;   /* parent directory missing, restore value */
-         s = p = p + 3;
-      } else if ( p[2] == '/' || !p[2] ) {  /* "/./" or "/." */
-         nc = p - s;
-         for ( i = 0; i < nc; ++i )
-            str[ni++] = s[i];
-         str[ni] = '/';
-         s = p = p + 2;
-      } else {                              /* "/.x" */
-         p += 2;
-      }
-   }
-
-   /* Append the rest of 'str' */
-   if ( str[ni] == '/' && !*s )  ++ni;
-   while ( (str[ni++] = *s++) );
-   return str;
-}
-
-/*
- * Resolve a "file:" URL
- */
-gchar *a_Url_resolve_file(const char *BaseUrl, const char *RelativeUrl)
-{
-   gchar *slash;
-   const char *rel;
-   gchar *NewUrl = NULL;
-
-   if ( !BaseUrl || !RelativeUrl )
-      return NULL;
-
-   rel = RelativeUrl;
-   if ( g_strncasecmp(RelativeUrl, "file:", 5) == 0 ) {
-      /* An absolute file-URL! */
-      rel = RelativeUrl + 5;
-      if ( rel[0] == '/' ) {
-         /* It was already solved (todo: squeeze it?) */
-         NewUrl = g_strdup(RelativeUrl);
-      } else {
-         /* File reference to current directory.
-          * ("file:" and "file:." show current dir */
-         char *cwd = g_get_current_dir();
-         if ( (rel[0] == '.' && !rel[1]) )
-            ++rel;
-         NewUrl = g_strdup_printf("file:%s%s%s", cwd, cwd[1] ? "/" : "", rel);
-      }
-      return NewUrl;
-   } else if ( a_Url_is_absolute(RelativeUrl) ) {
-      /* An absolute URL other than "file:" */
-      return g_strdup(RelativeUrl);
-   }
-
-   /* If we get here, 'BaseUrl' contains "file:" and 'rel' not */
-
-   if ( rel[0] == '/' ) {
-      /* Start from root dir */
-      NewUrl = g_strdup_printf("file:%s", rel);
-   } else if ( rel[0] == '#' ) {
-      /* Name reference, add it to BaseUrl. (todo: strip former '#') */
-      NewUrl = g_strdup_printf("%s%s", BaseUrl, RelativeUrl);
-   } else {
-      /* a file relative to BaseUrl */
-      slash = strrchr(BaseUrl, '/');
-      if ( !slash ) {
-         NewUrl = g_strdup_printf("file:%s", RelativeUrl);
-      } else if ( a_Misc_stristr(slash, ".htm") ) {
-         char *base = g_strndup(BaseUrl, slash - BaseUrl);
-         NewUrl = g_strdup_printf("%s/%s", base, RelativeUrl);
-         g_free(base);
-      } else {
-         NewUrl = g_strdup_printf("%s/%s", BaseUrl, RelativeUrl);
-      }
-   }
-   return NewUrl;
-}
-
-/*
- * Resolve a relative url into a newly allocated string.
- * This function is relatively tolerant to weird parameters (not 100%) --Jcid
- */
-gchar *a_Url_resolve_relative(const char *BaseUrl, const char *RelativeUrl)
-{
-   gchar *p;
-   gint i, path_index;
-   gchar *NewUrl = NULL;
-
-   if ( !BaseUrl || !RelativeUrl )
-      return NULL;
-
-   /* "file" method here */
-   if ( Url_match_method(BaseUrl, "file", 4) ||
-        Url_match_method(RelativeUrl, "file", 4) ){
-      NewUrl = a_Url_resolve_file(BaseUrl, RelativeUrl);
-      // g_print( "FRR New : %s\n", NewUrl);
-      return NewUrl;
-   }
-
-   if ( a_Url_is_absolute(RelativeUrl) ){
-      /* It has the "method:..." form. */
-      return g_strdup(RelativeUrl);
-   }
-
-   /* Parse method:/[/]name:port/ in BaseUrl
-    * e.g. http://hostname:port/ */
-   for (i = 0; BaseUrl[i] && BaseUrl[i] != ':'; i++);
-   for (i++; BaseUrl[i] && BaseUrl[i] == '/'; i++);
-   for (i++; BaseUrl[i] && BaseUrl[i] != '/'; i++);
-   path_index = i;
-
-   if ( RelativeUrl[0] == '/' ){
-      /* Get host from BaseUrl */
-      if ( i && BaseUrl[i] == '/' ) {
-         gchar *base = g_strndup(BaseUrl, i);
-         NewUrl = g_strdup_printf("%s%s", base, RelativeUrl);
-         g_free(base);
-      } else {
-         NewUrl = g_strdup_printf("%s%s", BaseUrl, RelativeUrl);
-      }
-   } else if ( RelativeUrl[0] == '#' ) {
-      /* Name reference, add it to BaseUrl. (todo: strip former '#') */
-      NewUrl = g_strdup_printf("%s%s", BaseUrl, RelativeUrl);
-   } else {
-      /* Get host and path from BaseUrl */
-      if ( BaseUrl[i] && (p = strrchr(BaseUrl, '/')) != NULL ) {
-         gchar *base = g_strndup(BaseUrl, p - BaseUrl);
-         NewUrl = g_strdup_printf("%s/%s", base, RelativeUrl);
-         g_free(base);
-      } else {
-         NewUrl = g_strdup_printf("%s/%s", BaseUrl, RelativeUrl);
-      }
-   }
-   a_Url_squeeze(NewUrl);
-// g_print("URR\n Base: %s\n Rel: %s\n New:%s\n", BaseUrl,RelativeUrl,NewUrl);
-   return NewUrl;
-}
-
-/*
- * Parse the url, packing the hostname and port into the arguments, and
- * returning the suffix. Return NULL in case of failure.
- */
-char *a_Url_parse(const char *url, char *hostname, guint hostname_size,
-                  gint *port)
-{
-   const char *CPtr = strchr(url, ':');
-   char *C1Ptr;
-   guint Size;
-
-   if (!CPtr || CPtr[1] != '/' || CPtr[2] != '/')
-      return NULL;
-
-   CPtr += 3;
-   if (!(C1Ptr = strpbrk(CPtr, ":/"))) {
-      Size = strlen(CPtr);
-      if (!hostname)
-         return (char *) CPtr + Size;
-      if (Size >= hostname_size)
-         return NULL;
-      memcpy(hostname, CPtr, Size);
-      hostname[Size] = '\0';
-      return (char *) CPtr + Size;
-   }
-   Size = (gulong) C1Ptr - (gulong) CPtr;
-   if (hostname) {
-      if (Size >= hostname_size)
-         return NULL;
-      memcpy(hostname, CPtr, Size);
-      hostname[Size] = '\0';
-   }
-   if (*C1Ptr != ':')
-      return (char *) C1Ptr;
-
-   if (port)
-      *port = strtoul(++C1Ptr, &C1Ptr, 0);
-
-   for (; *C1Ptr && *C1Ptr != '/'; C1Ptr++);
-   return C1Ptr;
-}
-
-
diff -pru dillo/src/IO/Url.h new/cvs/dillo.new/src/IO/Url.h
--- dillo/src/IO/Url.h	Sat Dec  9 12:43:51 2000
+++ new/cvs/dillo.new/src/IO/Url.h	Mon Mar  5 02:55:45 2001
@@ -14,38 +14,32 @@
 #include <string.h>
 #include <unistd.h>
 #include "IO.h"
-
-#define URN_OTHER  "()+,-.:=@;$_!*'/%?"
+#include "../urlparse.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
 
 /* Returns a file descriptor to read data on; meta data is sent on FD_TypeWrite */
-typedef gint (*__Open_t) (const char *url, void *data);
+typedef gint (*__Open_t) (const DilloURL *url, void *data);
 
 /*
  * Module functions
  */
 gint  a_Url_init (void);
-gint  a_Url_open (const char *url, void* Callback_Data);
-gint  a_Url_is_absolute (const char *url);
-char* a_Url_parse_hash  (const char *url);
-char* a_Url_squeeze(char *str);
-gchar* a_Url_resolve_relative(const char *BaseUrl, const char *RelativeUrl);
-char* a_Url_parse(const char *url, char *hostname, guint hostname_size,
-                  gint *port);
+gint  a_Url_open (const DilloURL *url, void* Callback_Data);
 
 
-extern char *HTTP_Proxy, *No_Proxy;
+extern DilloURL *HTTP_Proxy;
+extern char *No_Proxy;
 
 /*
  * External functions
  */
-extern gint a_Proto_get_url (const char *url, void*);
-extern gint a_About_get (const char *url, void*);
-extern gint a_File_get  (const char *url, void*);
-extern gint a_Http_get  (const char *url, void*);
+extern gint a_Proto_get_url (const DilloURL *Url, void*);
+extern gint a_About_get (const DilloURL *Url, void*);
+extern gint a_File_get  (const DilloURL *Url, void*);
+extern gint a_Http_get  (const DilloURL *Url, void*);
 extern void a_Http_freeall(void);
 
 #ifdef __cplusplus
diff -pru dillo/src/IO/about.c new/cvs/dillo.new/src/IO/about.c
--- dillo/src/IO/about.c	Sat Nov 11 01:54:47 2000
+++ new/cvs/dillo.new/src/IO/about.c	Mon Mar  5 02:53:29 2001
@@ -19,13 +19,15 @@
 /*
  * Push the right URL for each supported "about"
  */
-gint a_About_get(const char *url, void *Data)
+gint a_About_get(const DilloURL *Url, void *Data)
 {
-   char *loc;
-   const char *tail;
+   char *loc, *url;
+   const char *tail;   
    DilloWeb *web = Data;
 
-   tail = url + 6;              /* strlen ("about:") */
+   /*tail = url + 6;*/              /* strlen ("about:") */
+   url = a_Url_to_string(Url);
+   tail = url + 6;
    if (!strcmp(tail, "jwz"))
       loc = "http://www.jwz.org/";
    else if (!strcmp(tail, "raph"))
@@ -37,7 +39,10 @@ gint a_About_get(const char *url, void *
    else
       loc = "http://www.google.com/";
 
-   a_Nav_push(web ? web->bw : NULL, loc);
+   a_Nav_push(web ? web->bw : NULL, a_string_to_Url(loc));
+
+   if (url)
+      g_free(url);
 
    return -1;
 }
diff -pru dillo/src/IO/file.c new/cvs/dillo.new/src/IO/file.c
--- dillo/src/IO/file.c	Sat Dec  9 12:43:51 2000
+++ new/cvs/dillo.new/src/IO/file.c	Mon Mar  5 02:55:32 2001
@@ -34,6 +34,7 @@
 #include "IO.h"
 #include "../web.h"
 #include "../list.h"
+#include "../urlparse.h"
 
 typedef struct _DilloDir {
    gint FD_Write, FD_Read;
@@ -239,15 +240,16 @@ static char *File_content_type(const cha
  * Create a new file connection for 'Url', and asynchronously
  * feed the bytes that come back to the cache.
  */
-gint a_File_get(const char *Url, void *Data)
+gint a_File_get(const DilloURL *Url, void *Data)
 {
    char *filename;
    gint fd;
    struct stat sb;
    IOData_t *io;
    DilloWeb *web = Data;
+   char *urlstring = a_Url_to_string(Url);
 
-   filename = (char *) Url + 5;
+   filename = (char *) urlstring + 5; /* "file:" */
    if ( stat(filename, &sb) != 0 ) {
       /* stat failed, give file-not-found error. */
       File_not_found_msg(filename, web->bw);
@@ -256,10 +258,10 @@ gint a_File_get(const char *Url, void *D
 
    if (S_ISDIR(sb.st_mode)) {
       /* set up for reading directory */
-      fd = File_get_dir(Url);
+      fd = File_get_dir(urlstring);
    } else {
       /* set up for reading a file */
-      fd = File_get_file(Url);
+      fd = File_get_file(urlstring);
    }
 
    if ( fd < 0 ) {
@@ -271,11 +273,13 @@ gint a_File_get(const char *Url, void *D
       io->IOVec.iov_base = g_malloc(4096);
       io->IOVec.iov_len  = 4096;
       io->Callback = a_Cache_callback;
-      io->CbData = (void *) Url;
+      io->CbData = (void *)Url; /* (void *) g_strdup(urlstring); */
       io->FD = fd;
       a_IO_submit(io);
    }
 
+   g_free(urlstring);
+   
    return fd;
 }
 
diff -pru dillo/src/IO/http.c new/cvs/dillo.new/src/IO/http.c
--- dillo/src/IO/http.c	Tue Dec 12 23:16:18 2000
+++ new/cvs/dillo.new/src/IO/http.c	Mon Mar  5 03:12:36 2001
@@ -35,10 +35,10 @@
  * to free the struct to get rid of it. */
 typedef struct {
    gint SockFD;
-   const char *Url;
-   char hostname[256];
-   char *tail;
-   gint port;
+   DilloURL *Url;
+   /*   char hostname[256];
+	char *tail; 
+	gint port; */
    DilloWeb *Web;  /* Reference to client's Web structure */
 } SocketData_t;
 
@@ -125,7 +125,7 @@ static void Http_dns_callback(int Op, gu
    if ( Op ) {
       /* DNS failed */
       /* todo: send abort message to higher-level functions */
-      a_Interface_status(S->Web->bw, "ERROR: Dns can't solve %s", S->hostname);
+      a_Interface_status(S->Web->bw, "ERROR: Dns can't solve %s", S->Url->hostname);
       g_free(S);
       return;
    }
@@ -135,7 +135,7 @@ static void Http_dns_callback(int Op, gu
 
    /* Set remaining parms. */
    name.sin_family = AF_INET;
-   name.sin_port = htons (S->port);
+   name.sin_port = htons (S->Url->port);
    name.sin_addr.s_addr = htonl(ip_addr);
 
    status = connect(S->SockFD, (struct sockaddr *)&name, sizeof(name));
@@ -147,12 +147,12 @@ static void Http_dns_callback(int Op, gu
    }
 
    /* Create the query */
-   query = Http_query(S->tail, S->hostname, S->port);
-   /* g_print("Query: %s", query); */
+   query = Http_query(S->Url->path, S->Url->hostname, S->Url->port);
+   /* g_print("Query: >|%s|<", query); */
 
    /* send query */
    if ( S->Web->flags & WEB_RootUrl )
-      a_Interface_status(S->Web->bw, "Sending query to %s...", S->hostname);
+      a_Interface_status(S->Web->bw, "Sending query to %s...", S->Url->hostname);
    io = g_new(IOData_t, 1);
    io->Op = IOWrite;
    io->IOVec.iov_base = query;
@@ -168,7 +168,7 @@ static void Http_dns_callback(int Op, gu
    io2->IOVec.iov_base = g_malloc(4096);
    io2->IOVec.iov_len  = 4096;
    io2->Callback = a_Cache_callback;
-   io2->CbData = (void *) S->Url;
+   io2->CbData = (void *)S->Url;
    io2->FD = S->SockFD;
    a_IO_submit(io2);
 
@@ -181,29 +181,32 @@ static void Http_dns_callback(int Op, gu
  * We'll set some socket parameters; the rest will be set by Http_dns_callback
  * when the IP is known.
  */
-gint a_Http_get(const char *Url, void *Data)
+gint a_Http_get(const DilloURL *Url, void *Data)
 {
    gint fd;
    SocketData_t *S = g_new(SocketData_t, 1);
-
+   gchar* url = a_Url_to_string(Url);
+   
    /* Reference Web data */
    S->Web = Data;
 
+   S->Url = (DilloURL *)Url; /*a_Url_dup(Url);*/
+
    /* Hacked-in support for proxies, inspired by Olivier Aubert */
-   S->port = 80;
-   if (HTTP_Proxy && !(No_Proxy && strstr(Url, No_Proxy) != NULL)) {
-      a_Url_parse(HTTP_Proxy, S->hostname, sizeof(S->hostname), &S->port);
-      S->tail = (char *) Url;
+   a_Url_set_port(S->Url, 80);
+   if (HTTP_Proxy && !(No_Proxy && strstr(url, No_Proxy) != NULL)) {
+      S->Url->hostname = HTTP_Proxy->hostname;
+      S->Url->port = HTTP_Proxy->port;
+      S->Url->path = g_strdup(url);
    } else {
-      S->tail = a_Url_parse(Url, S->hostname, sizeof(S->hostname), &S->port);
+      S->Url->path = a_Url_parse(Url, S->Url->hostname, &S->Url->port);
    }
-   if (!S->tail) {
+   if (!S->Url->path) {
       g_free(S);
       return -1;
    }
 
    /* Set more socket parameters */
-   S->Url = Url;
    if ( (S->SockFD = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0 ) {
       /* Failed.. clean up */
       g_free(S);
@@ -213,17 +216,19 @@ gint a_Http_get(const char *Url, void *D
    /* set NONBLOCKING */
    fcntl(S->SockFD, F_SETFL, O_NONBLOCK | fcntl(S->SockFD, F_GETFL));
 
-
    /* Let the user know what we'll do */
    if ( S->Web->flags & WEB_RootUrl )
-      a_Interface_status(S->Web->bw, "DNS solving %s", S->hostname);
+      a_Interface_status(S->Web->bw, "DNS solving %s", S->Url->hostname);
 
    /* Let the DNS engine solve the hostname, and when done,
     * we'll try to connect the socket */
    fd = S->SockFD;
-   a_Dns_lookup(S->hostname, Http_dns_callback, (void *) S);
+   a_Dns_lookup(S->Url->hostname, Http_dns_callback, (void *) S);
    /* Http_dns_callback() frees 'S', so if it finishes before this function
     * resumes, S->SockFD is lost; that's why we use 'fd' instead.  --Jcid */
+
+   g_free(url);
+
    return fd;
 }
 
diff -pru dillo/src/IO/proto.c new/cvs/dillo.new/src/IO/proto.c
--- dillo/src/IO/proto.c	Wed Jan  3 00:28:54 2001
+++ new/cvs/dillo.new/src/IO/proto.c	Fri Mar 23 22:53:20 2001
@@ -23,6 +23,7 @@
 #include <sys/wait.h>
 #include "../web.h"
 #include "IO.h"
+#include "../urlparse.h"
 
 /* This module handles the Dillo plug-in api. */
 
@@ -36,8 +37,8 @@ struct _DilloProto {
 };
 
 static DilloProto plugins[] = {
-   {"dpi:", "/usr/local/bin/dpi_test"},
-   {"ftp:", "/usr/local/bin/dillo_ftp"}
+   {"dpi", "/usr/local/bin/dpi_test"},
+   {"ftp", "/usr/local/bin/dillo_ftp"}
 };
 
 /*
@@ -52,12 +53,12 @@ static gint Proto_prefix(const char *url
  * Find the plugin number to handle a given URL, or -1 if there is no
  * plugin for it.
  */
-static gint Proto_find(const char *url)
+static gint Proto_find(const DilloURL *url)
 {
    guint i;
 
    for (i = 0; i < sizeof(plugins) / sizeof(DilloProto); i++)
-      if (Proto_prefix(url, plugins[i].prefix) && 
+      if (Proto_prefix(url->protocol, plugins[i].prefix) && 
           access(plugins[i].handler, X_OK) == 0 )
          return i;
    return -1;
@@ -68,19 +69,22 @@ static gint Proto_find(const char *url)
 /*
  * Build a simple environment with PATH and REQUEST_URI for the execle() call
  */
-static void Proto_build_env(char **env, const char *url)
+static void Proto_build_env(char **env, const DilloURL *Url)
 {
    char *PATH = getenv("PATH");
+   char *url = a_Url_to_string(Url);
 
    env[0] = g_strconcat("PATH=", PATH, NULL);
    env[1] = g_strconcat("REQUEST_URI=", url, NULL);
    env[2] = NULL;
+
+   g_free(url);
 }
 
 /*
  * Search the right handler for the given url, and then execute the plugin
  */
-gint a_Proto_get_url(const char *Url, void *Data)
+gint a_Proto_get_url(const DilloURL *Url, void *Data)
 {
    char *env[MAX_ENV];
    pid_t child_pid;
@@ -125,7 +129,7 @@ gint a_Proto_get_url(const char *Url, vo
    io->IOVec.iov_base = g_malloc(4096);
    io->IOVec.iov_len  = 4096;
    io->Callback = a_Cache_callback;
-   io->CbData = (void *) Url;
+   io->CbData = (void *) Url; /* (void *) a_Url_to_string(Url); */
    io->FD = filedes[0];
    a_IO_submit(io);
 
diff -pru dillo/src/Makefile.am new/cvs/dillo.new/src/Makefile.am
--- dillo/src/Makefile.am	Wed Mar  7 16:38:12 2001
+++ new/cvs/dillo.new/src/Makefile.am	Fri Mar 23 22:56:28 2001
@@ -66,6 +66,8 @@ dillo_SOURCES = \
 	colors.c \
 	colors.h \
 	list.h \
-	pixmaps.h
+	pixmaps.h \
+	urlparse.c \
+	urlparse.h
 
-EXTRA_DIST = pixmaps_old.h chg srch
+EXTRA_DIST = pixmaps_old.h chg srch
\ No newline at end of file
diff -pru dillo/src/Makefile.in new/cvs/dillo.new/src/Makefile.in
--- dillo/src/Makefile.in	Wed Mar  7 16:38:13 2001
+++ new/cvs/dillo.new/src/Makefile.in	Fri Mar 23 23:01:38 2001
@@ -75,8 +75,7 @@ bin_PROGRAMS = dillo
 
 dillo_LDADD = IO/libDio.a @LIBJPEG_LIB@
 
-dillo_SOURCES =  	acconfig.h 	commands.c 	commands.h 	cache.c		cache.h		dw_bullet.c 	dw_bullet.h 	dw_container.c 	dw_container.h 	dw_embed_gtk.c		dw_embed_gtk.h		dw_gtk_scrolled_frame.c 	dw_gtk_scrolled_frame.h 	dw_gtk_scrolled_window.c 	dw_gtk_scrolled_window.h 	dw_gtk_statuslabel.c 	dw_gtk_statuslabel.h 	dw_gtk_viewport.c 	dw_gtk_viewport.h 	dw_hruler.c 	dw_hruler.h 	dw_image.c 	dw_image.h 	dw_page.c 	dw_page.h 	dw_widget.c 	dw_widget.h 	web.c		web.h		progressbar.c 	progressbar.h 	dillo.c 	dillo.h 	bookmark.c 	bookmark.h 	browser.h 	dicache.c 	dicache.h 	dns.c 	dns.h 	gif.c 	jpeg.c 	png.c 	html.c 	html.h 	image.c 	image.h 	misc.c 	misc.h 	interface.h 	interface.c 	nav.c 	nav.h 	plain.c 	menu.c 	menu.h 	prefs.c 	prefs.h 	colors.c 	colors.h 	list.h 	pixmaps.h
-
+dillo_SOURCES =      	acconfig.c  	commands.c 	commands.h 	cache.c		cache.h		dw_bullet.c 	dw_bullet.h 	dw_container.c 	dw_container.h 	dw_embed_gtk.c		dw_embed_gtk.h		dw_gtk_scrolled_frame.c 	dw_gtk_scrolled_frame.h 	dw_gtk_scrolled_window.c 	dw_gtk_scrolled_window.h 	dw_gtk_statuslabel.c 	dw_gtk_statuslabel.h 	dw_gtk_viewport.c 	dw_gtk_viewport.h 	dw_hruler.c 	dw_hruler.h 	dw_image.c 	dw_image.h 	dw_page.c 	dw_page.h 	dw_widget.c 	dw_widget.h 	web.c		web.h		progressbar.c 	progressbar.h 	dillo.c 	dillo.h 	bookmark.c 	bookmark.h 	browser.h 	dicache.c 	dicache.h 	dns.c 	dns.h 	gif.c 	jpeg.c 	png.c 	html.c 	html.h 	image.c 	image.h 	misc.c 	misc.h 	interface.h 	interface.c 	nav.c 	nav.h 	plain.c 	menu.c 	menu.h 	prefs.c 	prefs.h 	colors.c 	colors.h 	list.h	pixmaps.h	urlparse.c 	urlparse.h
 
 EXTRA_DIST = pixmaps_old.h chg srch
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -94,7 +93,7 @@ dw_embed_gtk.o dw_gtk_scrolled_frame.o d
 dw_gtk_statuslabel.o dw_gtk_viewport.o dw_hruler.o dw_image.o dw_page.o \
 dw_widget.o web.o progressbar.o dillo.o bookmark.o dicache.o dns.o \
 gif.o jpeg.o png.o html.o image.o misc.o interface.o nav.o plain.o \
-menu.o prefs.o colors.o
+menu.o prefs.o colors.o urlparse.o
 dillo_DEPENDENCIES =  IO/libDio.a
 dillo_LDFLAGS = 
 CFLAGS = @CFLAGS@
@@ -116,7 +115,7 @@ DEP_FILES =  .deps/bookmark.P .deps/cach
 .deps/dw_image.P .deps/dw_page.P .deps/dw_widget.P .deps/gif.P \
 .deps/html.P .deps/image.P .deps/interface.P .deps/jpeg.P .deps/menu.P \
 .deps/misc.P .deps/nav.P .deps/plain.P .deps/png.P .deps/prefs.P \
-.deps/progressbar.P .deps/web.P
+.deps/progressbar.P .deps/web.P .deps/urlparse.P
 SOURCES = $(dillo_SOURCES)
 OBJECTS = $(dillo_OBJECTS)
 
diff -pru dillo/src/bookmark.c new/cvs/dillo.new/src/bookmark.c
--- dillo/src/bookmark.c	Sun Mar 18 00:01:29 2001
+++ new/cvs/dillo.new/src/bookmark.c	Mon Mar  5 01:52:31 2001
@@ -50,7 +50,7 @@ typedef struct _CallbackInfo CallbackInf
 
 struct _Bookmark {
    char *title;
-   char *url;
+   DilloURL *url;
    GtkWidget *menuitem;
 };
 
@@ -63,8 +63,8 @@ struct _CallbackInfo {
  * Forward declarations
  */
 static void Bookmarks_load_to_menu(FILE *fp);
-static void Bookmarks_file_op(gint operation, char *title, char *url);
-static void Bookmarks_save_to_file(FILE *fp, char *title, char *url);
+static void Bookmarks_file_op(gint operation, char *title, DilloURL *url);
+static void Bookmarks_save_to_file(FILE *fp, char *title, DilloURL *url);
 static char *Bookmarks_search_line(char *line, char *start_text, char *end_text);
 
 /*
@@ -125,16 +125,17 @@ void Bookmarks_add_to_menu(BrowserWindow
 /*
  * ?
  */
-static GtkWidget *Bookmarks_insert(const char *title, const char *url)
+static GtkWidget *Bookmarks_insert(const char *title, DilloURL *Url)
 {
    GtkWidget *menuitem;
+   gchar *url = a_Url_to_string(Url);
 
    menuitem = gtk_menu_item_new_with_label(title ? title : url);
    gtk_widget_show(menuitem);
 
    a_List_add(bookmarks, num_bookmarks, sizeof(*bookmarks), num_bookmarks_max);
    bookmarks[num_bookmarks].title = g_strdup(title ? title : url);
-   bookmarks[num_bookmarks].url = g_strdup(url);
+   bookmarks[num_bookmarks].url = Url;
    bookmarks[num_bookmarks].menuitem = menuitem;
    num_bookmarks++;
    return menuitem;
@@ -151,19 +152,20 @@ void a_Bookmarks_add(GtkWidget *widget, 
 #ifdef TITLE39
    gboolean allocated = FALSE;
 #endif
-   char *title, *url;
+   char *title;
+   DilloURL *url;
    GtkWidget *menuitem;
 
    title = bw->menu_popup.info.title;
    url = bw->menu_popup.info.url;
 
    /* Don't allow an empty url */
-   if ( !url || !*url)
+   if ( !url ) /* LBS: make a Url_is_empty() ??? || !*url) */
       return;
 
    /* If the page has no title, lets use the URL */
    if ( !title || !*title )
-      title = url;
+      title = a_Url_to_string(url);
 
 #ifdef TITLE39
    if (strlen (title) > 39) {
@@ -213,7 +215,7 @@ void Bookmarks_close(void)
  * Performs operations on the bookmark file..
  * for first call, title is the filename
  */
-static void Bookmarks_file_op(gint operation, char *title, char *url)
+static void Bookmarks_file_op(gint operation, char *title, DilloURL *url)
 {
    static FILE *fp;
    static gint init = 1;
@@ -249,9 +251,9 @@ static void Bookmarks_file_op(gint opera
 /*
  * Save bookmarks to ~/.dillo/bookmarks.html
  */
-static void Bookmarks_save_to_file(FILE *fp, char *title, char *url)
+static void Bookmarks_save_to_file(FILE *fp, char *title, DilloURL *Url)
 {
-   char *buf;
+   char *buf, *url = a_Url_to_string(Url);
 
    fseek(fp, 0L, SEEK_END);
 
@@ -262,12 +264,13 @@ static void Bookmarks_save_to_file(FILE 
       sprintf(buf, "<li><A HREF=%c%s%c>%s</A></li>\n", D_QUOTE, url,
               D_QUOTE, title);
    } else {
-      buf = g_malloc(strlen(url) + strlen(url) + 128);
+      buf = g_malloc(2*strlen(url) + 128);
       sprintf(buf, "<li><A HREF=%c%s%c>%s</A></li>\n", D_QUOTE, url,
               D_QUOTE, url);
    }
    fwrite(buf, strlen(buf), 1, fp);
    g_free(buf);
+   g_free(url);
 }
 
 /*
@@ -299,7 +302,7 @@ static void Bookmarks_load_to_menu(FILE 
          continue;
       }
 
-      menuitem = Bookmarks_insert(title, url);
+      menuitem = Bookmarks_insert(title, a_string_to_Url(url));
       /* for (i = 0; i < num_bw; i++) 
        *    Bookmarks_add_to_menu(browser_window[i], menuitem); */
       Bookmarks_add_to_menu(browser_window[0], menuitem, i);
@@ -310,7 +313,7 @@ static void Bookmarks_load_to_menu(FILE 
 }
 
 /*
- * Copy bookmarks when new browser windows are opened.
+ * Load bookmarks when new browser windows are opened.
  * Called by 'a_Menu_mainbar_new()'
  */
 void a_Bookmarks_fill_new_menu(BrowserWindow *bw)
@@ -318,6 +321,7 @@ void a_Bookmarks_fill_new_menu(BrowserWi
    gint i;
    GtkWidget *menuitem;
 
+   g_print("Loading bookmarks...\n");
    for (i = 0; i < num_bookmarks; i++) {
      menuitem = gtk_menu_item_new_with_label(bookmarks[i].title);
      gtk_widget_show(menuitem);
diff -pru dillo/src/browser.h new/cvs/dillo.new/src/browser.h
--- dillo/src/browser.h	Thu Dec 28 22:06:30 2000
+++ new/cvs/dillo.new/src/browser.h	Mon Mar  5 01:01:54 2001
@@ -6,9 +6,10 @@ typedef struct _BrowserWindow BrowserWin
 typedef struct _DilloMenuPopup DilloMenuPopup;
 
 #include "image.h"
+#include "urlparse.h"
 
 typedef struct {
-    char *url;
+    DilloURL *url;
     char *title;
     /* maybe put some more stuff here:
      * + scroll position
@@ -17,7 +18,7 @@ typedef struct {
 } DilloNav;
 
 typedef struct {
-    char *Url;   /* URL-key for this cache connection */
+    DilloURL *Url;   /* URL-key for this cache connection */
     gint Flags;  /* {WEB_RootUrl, WEB_Image, WEB_Download} */
 } BwUrls;
 
diff -pru dillo/src/cache.c new/cvs/dillo.new/src/cache.c
--- dillo/src/cache.c	Tue Dec 12 23:16:18 2000
+++ new/cvs/dillo.new/src/cache.c	Mon Mar  5 01:56:24 2001
@@ -37,16 +37,16 @@
  */
 
 typedef struct {
-   const char *Url;      /* Cached Url. Url is used as a primary Key */
-   const char *Type;     /* MIME type string */
-   GString *Header;      /* HTTP header */
-   const char *Location; /* New URI for redirects */
-   void *Data;           /* Pointer to raw data */
-   size_t ValidSize,     /* Actually size of valid range */
-          TotalSize,     /* Goal size of the whole data (0 if unknown) */
-          BuffSize;      /* Buffer Size for unknown length transfers */
-   guint Flags;          /* Look Flag Defines in cache.h */
-   IOData_t *io;         /* Pointer to IO data */
+   DilloURL *Url;            /* Cached Url. Url is used as a primary Key */
+   const char *Type;         /* MIME type string */
+   GString *Header;          /* HTTP header */
+   const DilloURL *Location; /* New URI for redirects */
+   void *Data;               /* Pointer to raw data */
+   size_t ValidSize,         /* Actually size of valid range */
+          TotalSize,         /* Goal size of the whole data (0 if unknown) */
+          BuffSize;          /* Buffer Size for unknown length transfers */
+   guint Flags;              /* Look Flag Defines in cache.h */
+   IOData_t *io;             /* Pointer to IO data */
 } CacheData_t;
 
 
@@ -77,9 +77,9 @@ void a_Cache_freeall(void) { return; }
 /*
  * Set safe values for a new cache entry
  */
-void Cache_init_entry(CacheData_t *NewEntry, const char *Url)
+void Cache_init_entry(CacheData_t *NewEntry, const DilloURL *Url)
 {
-   NewEntry->Url = g_strdup(Url);
+   NewEntry->Url = a_Url_dup(Url);
    NewEntry->Type = NULL;
    NewEntry->Header = g_string_new("");
    NewEntry->Location = NULL;
@@ -94,7 +94,7 @@ void Cache_init_entry(CacheData_t *NewEn
 /*
  * Allocate and set a new entry in the cache list
  */
-CacheData_t *Cache_add_entry(const char *Url)
+CacheData_t *Cache_add_entry(const DilloURL *Url)
 {
    /* Allocate memory */
    a_List_add(CacheList, CacheListSize, sizeof(*CacheList), CacheListMax);
@@ -123,7 +123,7 @@ gint a_Cache_make_client_key(void)
  *  - Return a unique number for identifying the client.
  */
 gint
- Cache_enqueue_client(const char *Url, CA_Callback_t Callback, void *CbData)
+ Cache_enqueue_client(const DilloURL *Url, CA_Callback_t Callback, void *CbData)
 {
    gint ClientKey;
    CacheClient_t *NewClient;
@@ -147,13 +147,13 @@ gint
  * If 'Url' isn't cached, return NULL
  * (We search backwards to speed up the process)
  */
-CacheData_t *Cache_search(const char *Url)
+CacheData_t *Cache_search(const DilloURL *Url)
 {
    gint i;
 
    for ( i = CacheListSize - 1; i >= 0; --i )
-      if ( strcmp(Url, CacheList[i].Url) == 0 )
-         return (CacheList + i);
+      if ( ! a_Url_cmp(Url, CacheList[i].Url) )
+	 return (CacheList + i);
    return NULL;
 }
 
@@ -162,13 +162,18 @@ CacheData_t *Cache_search(const char *Ur
  * If 'Url' isn't cached, return NULL
  * ===> 'Url' must a be a pointer to entry->Url <===
  */
-CacheData_t *Cache_fast_search(const char *Url)
+CacheData_t *Cache_fast_search(const DilloURL *Url)
 {
    gint i;
 
    for ( i = CacheListSize - 1; i >= 0; --i )
-      if ( Url == CacheList[i].Url )
-         return (CacheList + i);
+     /* LBS: Currently this is a `hack' to work with incomplete
+	URL-struct in urlparse.[ch] */      
+      if ( !a_Url_cmp(Url, CacheList[i].Url))
+	 return (CacheList + i);  
+      /*if ( Url == CacheList[i].Url )
+	return (CacheList + i); */
+
    return NULL;
 }
 
@@ -182,7 +187,7 @@ CacheData_t *Cache_fast_search(const cha
  *
  * Return value: A primary key for identifying the client.
  */
-gint Cache_open_url(const char *Url, CA_Callback_t Call, void *CbData)
+gint Cache_open_url(const DilloURL *Url, CA_Callback_t Call, void *CbData)
 {
    gint ClientKey;
    CacheData_t *entry = Cache_search(Url);
@@ -206,7 +211,7 @@ gint Cache_open_url(const char *Url, CA_
  * from there. If it misses, set up a new connection.
  * Return value: A primary key for identifying the client.
  */
-gint a_Cache_open_url(const char *Url, CA_Callback_t Call, void *CbData)
+gint a_Cache_open_url(const DilloURL *Url, CA_Callback_t Call, void *CbData)
 {
    gint ClientKey;
    DICacheEntry *DicEntry;
@@ -237,7 +242,7 @@ gint a_Cache_open_url(const char *Url, C
  * Return the pointer to URL 'Data' in the cache.
  * (We also return its size in 'Size')
  */
-char *a_Cache_url_read(const char *Url, gint *Size)
+char *a_Cache_url_read(const DilloURL *Url, gint *Size)
 {
    CacheData_t *entry = Cache_search(Url);
 
@@ -306,7 +311,7 @@ void Cache_parse_header(CacheData_t *ent
       if ( header[11] == '1' )
          /* 301 Moved Permanently */
          entry->Flags |= CA_ForceRedirect;
-      entry->Location = Cache_parse_field(header, "Location");
+      entry->Location = a_string_to_Url(Cache_parse_field(header, "Location"));
 
    } else if ( strncmp(header + 9, "404", 3) == 0 ) {
       entry->Flags |= CA_NotFound;
@@ -378,7 +383,7 @@ gint Cache_get_header(IOData_t *io, Cach
 void a_Cache_callback(int Op, void *VPtr)
 {
    IOData_t *io = VPtr;
-   const char *Url = io->CbData;
+   DilloURL *Url = io->CbData;
    CacheData_t *entry = Cache_fast_search(Url);
    gint Status, len;
 
@@ -440,19 +445,20 @@ void a_Cache_callback(int Op, void *VPtr
  */
 gint Cache_redirect(CacheData_t *entry, gint Flags, BrowserWindow *bw)
 {
-   gchar *NewUrl;
+   DilloURL *NewUrl;
+   gchar *entry_url = a_Url_to_string(entry->Url), *entry_location = a_Url_to_string(entry->Location);
 
    if ( ((entry->Flags & CA_Redirect) && entry->Location) &&
         ((entry->Flags & CA_ForceRedirect) || !entry->ValidSize ||
          entry->ValidSize < 1024 ) ) {
 
-      g_print(">>>Redirect from: %s\n to %s\n", entry->Url, entry->Location);
+      g_print(">>>Redirect from: %s\n to %s\n", entry_url, entry_location);
       g_print("%s", entry->Header->str);
 
       if ( Flags & WEB_RootUrl ) {
          /* Redirection of the main page */
          a_Nav_remove_top_url(bw, entry->Url);
-         NewUrl = a_Url_resolve_relative(entry->Url, entry->Location);
+         NewUrl = a_Url_resolve_relative(entry->Url, entry_location);
          a_Nav_push(bw, NewUrl);
          g_free(NewUrl);
       } else {
@@ -464,6 +470,9 @@ gint Cache_redirect(CacheData_t *entry, 
          }
       }
    }
+
+   g_free(entry_url);
+   g_free(entry_location);
    return 0;
 }
 
@@ -489,7 +498,7 @@ void a_Cache_null_client(int Op, CacheCl
 void Cache_process_queue(CacheData_t *entry)
 {
    static gboolean Busy = FALSE;
-   const char *Url = entry->Url;
+   const DilloURL *Url = entry->Url;
    CacheClient_t *Client;
    DilloWeb *ClientWeb;
    gint i;
@@ -566,7 +575,7 @@ void Cache_delayed_process_queue(CacheDa
  * todo: Handle running clients on an entry (currently avoided).
  *       That must be implemented after the IO abort mechanism. --Jcid
  */
-void a_Cache_remove_entry(char *url)
+void a_Cache_remove_entry(DilloURL *url)
 {
    gint i;
    CacheData_t *entry;
@@ -575,7 +584,7 @@ void a_Cache_remove_entry(char *url)
    if ( (entry = Cache_search(url)) != NULL ) {
       /* Check for a running client on the cache entry */
       for ( i = 0; (Client = g_slist_nth_data(ClientQueue, i)); ++i ) {
-         if ( strcmp(Client->Url, entry->Url) == 0 )
+         if ( ! a_Url_cmp(Client->Url, entry->Url) )
             return;
       }
       a_List_remove(CacheList, entry - CacheList, CacheListSize);
@@ -606,7 +615,7 @@ void a_Cache_disable_client(gint Key)
 /*
  * If the entry has no client, abort its io and set the CA_Stopped flag
  */
-void a_Cache_stop_entry(gchar *Url)
+void a_Cache_stop_entry(DilloURL *Url)
 {
    gint i;
    CacheClient_t *Client;
@@ -616,7 +625,7 @@ void a_Cache_stop_entry(gchar *Url)
    if ( entry && entry->io && !(entry->Flags & CA_GotData) ) {
       /* An incomplete entry... */
       for ( i = 0; (Client = g_slist_nth_data(ClientQueue, i)); ++i ) {
-         if ( strcmp(Url, Client->Url) == 0 ) {
+         if ( ! a_Url_cmp(Url, Client->Url)) {
             found = TRUE;
             break;
          }
diff -pru dillo/src/cache.h new/cvs/dillo.new/src/cache.h
--- dillo/src/cache.h	Sat Dec  9 12:43:46 2000
+++ new/cvs/dillo.new/src/cache.h	Mon Mar  5 00:51:45 2001
@@ -3,6 +3,7 @@
 
 #include <glib.h>
 
+#include "urlparse.h"
 
 /*
  * Cache Op codes
@@ -32,29 +33,29 @@ typedef void (*CA_Callback_t)(int Op, Ca
  * Data structure for cache clients.
  */
 struct _CacheClient {
-   gint Key;                /* Primary Key for this client */
-   const char *Url;         /* Pointer to a cache entry Url */
-   guchar *Buf;             /* Pointer to cache-data */
-   guint BufSize;           /* Valid size of cache-data */
-   CA_Callback_t Callback;  /* Client function */
-   void *CbData;            /* Client function data */
-   void *Web;               /* Pointer to the Web structure of our client */
+   gint Key;                   /* Primary Key for this client */
+   const DilloURL *Url;        /* Pointer to a cache entry Url */
+   guchar *Buf;                /* Pointer to cache-data */
+   guint BufSize;              /* Valid size of cache-data */
+   CA_Callback_t Callback;     /* Client function */
+   void *CbData;               /* Client function data */
+   void *Web;                  /* Pointer to the Web structure of our client */
 };
 
 /*
  * Function prototypes
  */
 void a_Cache_redirect_url(const char* Orig_URL, const char* To_Url);
-gint a_Cache_open_url(const char *url, CA_Callback_t Call, void *CbData);
+gint a_Cache_open_url(const DilloURL *url, CA_Callback_t Call, void *CbData);
 void a_Cache_callback(int Op, void *VPtr);
 
-char *a_Cache_url_read(const char *url, gint *size);
-void a_Cache_remove_entry(char *url);
+char *a_Cache_url_read(const DilloURL *url, gint *size);
+void a_Cache_remove_entry(DilloURL *url);
 void a_Cache_freeall(void);
 void a_Cache_null_client(int Op, CacheClient_t *Client);
 gint a_Cache_make_client_key(void);
 void a_Cache_disable_client(gint Key);
-void a_Cache_stop_entry(gchar *Url);
+void a_Cache_stop_entry(DilloURL *Url);
 
 #endif /* __CACHE_H__ */
 
diff -pru dillo/src/colors.c new/cvs/dillo.new/src/colors.c
--- dillo/src/colors.c	Sun Mar 18 00:01:29 2001
+++ new/cvs/dillo.new/src/colors.c	Fri Mar 23 23:07:33 2001
@@ -225,7 +225,7 @@ gint32 a_Color_parse (char *subtag, gint
             low = mid + 1;
          else {
             ret_color = color_keyword[mid].val;
-            break;
+              break;
          }
       }
    }
diff -pru dillo/src/commands.c new/cvs/dillo.new/src/commands.c
--- dillo/src/commands.c	Sun Mar  4 16:21:21 2001
+++ new/cvs/dillo.new/src/commands.c	Sun Mar  4 01:44:49 2001
@@ -284,7 +284,7 @@ void a_Commands_viewbm_callback(GtkWidge
    /*  -RL :: strlen ("file:/")  is  6 */
    url = g_malloc (strlen (bmfile) + 7);
    sprintf(url, "file:/%s", bmfile);
-   a_Nav_push (bw, url);
+   a_Nav_push (bw, a_string_to_Url(url));
    g_free (bmfile);
    g_free (url);
 }
@@ -300,7 +300,7 @@ void a_Commands_helphome_callback(GtkWid
 {
    BrowserWindow *bw = (BrowserWindow *) client_data;
 
-   a_Nav_push(bw, DILLO_HOME);
+   a_Nav_push(bw, a_string_to_Url(DILLO_HOME));
 }
 
 /*
@@ -343,7 +343,8 @@ void a_Commands_set_selection_callback(G
 
    if (gtk_selection_owner_set(widget,GDK_SELECTION_PRIMARY,GDK_CURRENT_TIME)){
       /* --EG: Why would it fail ? */
-      Selection = g_strdup(bw->menu_popup.info.url);
+      /* Selection = g_strdup(bw->menu_popup.info.url); */
+      Selection = a_Url_to_string(bw->menu_popup.info.url);
    }
 }
 
diff -pru dillo/src/dicache.c new/cvs/dillo.new/src/dicache.c
--- dillo/src/dicache.c	Sun Mar  4 16:21:21 2001
+++ new/cvs/dillo.new/src/dicache.c	Mon Mar  5 02:01:12 2001
@@ -50,7 +50,7 @@ void a_Dicache_init(void)
 /*
  * Create and initialize a new cache entry with safe values
  */
-DICacheEntry *a_Dicache_entry_new(const gchar *Url)
+DICacheEntry *a_Dicache_entry_new(DilloURL *Url)
 {
    static gint DicKey = 0;
    DICacheEntry *entry;
@@ -59,7 +59,7 @@ DICacheEntry *a_Dicache_entry_new(const 
 
    entry = g_new(DICacheEntry, 1);
    entry->Key = DicKey;
-   entry->url = g_strdup(Url);
+   entry->url = a_Url_dup(Url);
    entry->width = 0;
    entry->height = 0;
    entry->type = DILLO_IMG_TYPE_NOTSET;
@@ -91,12 +91,12 @@ void a_Dicache_add_entry(DICacheEntry *e
  * Search an entry in the dicache (given the Url)
  * Return value: a pointer to the entry if found; NULL otherwise.
  */
-DICacheEntry *a_Dicache_get_entry(const gchar* Url)
+DICacheEntry *a_Dicache_get_entry(const DilloURL* Url)
 {
    gint i;
 
    for (i = dicache_size - 1; i >= 0; i--) {
-      if ( !strcmp(Url, dicache[i]->url) )
+      if ( ! a_Url_cmp(Url, dicache[i]->url) )
          return dicache[i];
    }
    return NULL;
@@ -120,14 +120,14 @@ DICacheEntry *a_Dicache_get_entry_by_key
 /*
  * Remove a dicache entry (Using Url or DicKey as primary Key)
  */
-void a_Dicache_remove(const gchar *Url, gint DicKey)
+void a_Dicache_remove(const DilloURL *Url, gint DicKey)
 {
    gint i;
    DICacheEntry *entry;
 
    for (i = 0; i < dicache_size; ++i) {
       entry = dicache[i];
-      if ( (Url && !strcmp(Url, entry->url)) || DicKey == entry->Key )
+      if ( (Url && !a_Url_cmp(Url, entry->url)) || DicKey == entry->Key )
          break;
    }
 
diff -pru dillo/src/dicache.h new/cvs/dillo.new/src/dicache.h
--- dillo/src/dicache.h	Sat Nov 11 01:54:39 2000
+++ new/cvs/dillo.new/src/dicache.h	Mon Mar  5 00:35:35 2001
@@ -18,7 +18,7 @@ typedef struct _DICacheEntry DICacheEntr
 
 struct _DICacheEntry {
    gint Key;               /* A primary Key for this entry */
-   char *url;              /* Image URL for this entry */
+   DilloURL *url;          /* Image URL for this entry */
    gint width, height;     /* As taken from image data */
    DilloImgType type;      /* Image type */
    guchar *cmap;           /* Color map */
@@ -34,8 +34,8 @@ struct _DICacheEntry {
 
 void a_Dicache_init (void);
 
-DICacheEntry *a_Dicache_entry_new(const gchar *Url);
-DICacheEntry *a_Dicache_get_entry(const gchar* Url);
+DICacheEntry *a_Dicache_entry_new(DilloURL *Url);
+DICacheEntry *a_Dicache_get_entry(const DilloURL *Url);
 DICacheEntry *a_Dicache_get_entry_by_key(gint Key);
 void a_Dicache_add_entry(DICacheEntry *entry);
 
@@ -50,6 +50,6 @@ void a_Dicache_write(DilloImage *Image, 
 void a_Dicache_close(gint DicKey, CacheClient_t *Client);
 
 void a_Dicache_freeall(void);
-void a_Dicache_remove(const gchar *Url, gint DicKey);
+void a_Dicache_remove(const DilloURL *Url, gint DicKey);
 
 #endif /* __DILLODICACHE_H__ */
diff -pru dillo/src/dillo.c new/cvs/dillo.new/src/dillo.c
--- dillo/src/dillo.c	Wed Mar  7 16:38:13 2001
+++ new/cvs/dillo.new/src/dillo.c	Fri Mar 23 23:10:00 2001
@@ -102,13 +102,13 @@ gint main(int argc, char *argv[])
    Dillo_check_splash_screen(file);
    start_url = g_string_new("file:");
    g_string_append(start_url, file);
-   a_Nav_push(bw, start_url->str);
+   a_Nav_push(bw, a_string_to_Url(start_url->str));
    g_free(file);
    g_string_free(start_url, TRUE);
 
    if (argc == 2) {
       if (a_Url_is_absolute(argv[1])) {
-         a_Nav_push(bw, argv[1]);
+         a_Nav_push(bw, a_string_to_Url(argv[1]));
       } else {
          /* CP: Would be wise to verify that URLs stay within those bounds */
          char url[1024];
@@ -120,7 +120,7 @@ gint main(int argc, char *argv[])
             /* CP: Would also be wise to postpend '/' on dirs and domain
              * names. */
             sprintf(url, "file:%s", argv[1]);
-            a_Nav_push(bw, url);
+            a_Nav_push(bw, a_string_to_Url(url));
          }
       }
    }
diff -pru dillo/src/dns.c new/cvs/dillo.new/src/dns.c
--- dillo/src/dns.c	Wed Mar  7 16:38:13 2001
+++ new/cvs/dillo.new/src/dns.c	Fri Mar 23 23:11:19 2001
@@ -217,8 +217,8 @@ void *Dns_server(void *data)
    struct hostent sh;
 #endif
 
-/* sigset_t current_sigs;
- *
+/* sigset_t current_sigs; 
+ *  
  * pthread_sigmask(SIG_BLOCK, NULL, NULL);
  * pthread_sigmask(SIG_BLOCK, NULL, &current_sigs);
  * pthread_sigmask(SIG_BLOCK, &current_sigs, NULL);
diff -pru dillo/src/dw_page.c new/cvs/dillo.new/src/dw_page.c
--- dillo/src/dw_page.c	Sun Mar 18 00:01:29 2001
+++ new/cvs/dillo.new/src/dw_page.c	Fri Mar 23 23:25:09 2001
@@ -316,7 +316,7 @@ static void Dw_page_destroy (GtkObject *
 /*
  * Standard Dw function
  */
-static void Dw_page_size_request (DwWidget *widget,
+static void Dw_page_size_request (DwWidget      *widget,
                                   DwRequisition *requisition)
 {
    DwPage *page;
@@ -364,8 +364,8 @@ static void Dw_page_size_request (DwWidg
    requisition->width = page->real_width;
 
    if (page->num_lines > 0)
-      requisition->ascent =
-         page->lines[page->num_lines - 1].y_top +
+      requisition->ascent = 
+	 page->lines[page->num_lines - 1].y_top +
          page->lines[page->num_lines - 1].y_ascent +
          page->lines[page->num_lines - 1].y_descent;
    else
@@ -1227,9 +1227,11 @@ static gint Dw_page_button_release(DwWid
           * Url.c functions can't deal with that yet
           */
          if( page->x_click > 0 ) {
+	    char *url = a_Url_to_string(page->links[link_pressed].url);
             sprintf(full_url,"%s?%d,%d",
-                    page->links[link_pressed].url,
+                    url,
                     page->x_click,page->y_click);
+	    g_free(url);
             gtk_signal_emit (GTK_OBJECT (widget), page_signals[LINK_CLICKED],
                              full_url, event);
          } else
@@ -1362,13 +1364,13 @@ gint a_Dw_page_find_font(DwPage *page, c
 /*
  * Create a new link, return the index.
  */
-gint a_Dw_page_new_link(DwPage *page, const char *url, const char *alt)
+gint a_Dw_page_new_link(DwPage *page, const DilloURL *url, const char *alt)
 {
    gint nl;
 
    nl = page->num_links;
    a_List_add(page->links, nl, sizeof(*page->links), page->num_links_max);
-   page->links[nl].url = url ? g_strdup(url) : NULL;
+   page->links[nl].url = url ? a_Url_dup(url) : NULL;
    page->links[nl].alt = alt ? g_strdup(alt) : NULL;
    return page->num_links++;
 }
diff -pru dillo/src/dw_page.h new/cvs/dillo.new/src/dw_page.h
--- dillo/src/dw_page.h	Sun Mar  4 20:14:20 2001
+++ new/cvs/dillo.new/src/dw_page.h	Mon Mar  5 00:54:44 2001
@@ -8,6 +8,7 @@
 
 #include <gdk/gdk.h>
 #include "dw_container.h"
+#include "urlparse.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -53,7 +54,7 @@ struct _DwPageFont
 
 struct _DwPageLink
 {
-   char *url;
+   DilloURL *url;
    char *alt;
 };
 
@@ -260,7 +261,7 @@ void a_Dw_page_update_begin (DwPage *pag
 void a_Dw_page_update_end (DwPage *page);
 void a_Dw_page_init_attr (DwPage *page, DwPageAttr *attr);
 gint a_Dw_page_find_font (DwPage *page, const DwPageFont *font);
-gint a_Dw_page_new_link (DwPage *page, const char *url, const char *alt);
+gint a_Dw_page_new_link (DwPage *page, const DilloURL *url, const char *alt);
 gint a_Dw_page_find_color (DwPage *page, gint32 color);
 gint a_Dw_page_add_attr (DwPage *page, const DwPageAttr *attr);
 void a_Dw_page_add_text (DwPage *page, char *text, gint attr);
diff -pru dillo/src/html.c new/cvs/dillo.new/src/html.c
--- dillo/src/html.c	Sun Mar 18 00:01:29 2001
+++ new/cvs/dillo.new/src/html.c	Sat Mar 24 01:08:52 2001
@@ -44,14 +44,15 @@
 #include "progressbar.h"
 #include "prefs.h"
 
+
 typedef void (*TagFunct) (DilloHtml *Html, char *Tag, gint Tagsize);
 
 
 /*
  * Forward declarations
  */
-static gint Html_get_attr(const char *tag, gint tagsize, const char *param,
-                          char *data, gint datasize);
+static gint Html_get_attr(const char *tag, gint tagsize, const char *param, 
+			  char *data, gint datasize);
 static gchar *Html_get_attr_p(const char *tag, gint tagsize,
                               const char *attrname, gint flags);
 static void Html_add_widget(DilloHtml *html, DwWidget *widget,
@@ -157,15 +158,15 @@ static void Html_lb_free(void *D)
  * Handle the status function generated by the dw scroller,
  * and show the url in the browser status-bar.
  */
-static void Html_handle_status(BrowserWindow *bw, const char *url)
+static void Html_handle_status(BrowserWindow *bw, const DilloURL *url)
 {
-   a_Interface_status(bw, "%s", url ? url : "");
+   a_Interface_status(bw, "%s", url ? url->original_url : "");
 }
 
 /*
  * Popup the link menu ("link_pressed" callback of the page)
  */
-static void Html_link_menu(BrowserWindow *bw, char *url, GdkEventButton *event)
+static void Html_link_menu(BrowserWindow *bw, DilloURL *url, GdkEventButton *event)
 {
    if(event->button == 3) {
       bw->menu_popup.info.title = "";
@@ -179,7 +180,7 @@ static void Html_link_menu(BrowserWindow
 /*
  * Activate a link ("link_clicked" callback of the page)
  */
-static void Html_link_clicked(BrowserWindow *bw, char *url,
+static void Html_link_clicked(BrowserWindow *bw, DilloURL *url,
                               GdkEventButton *event)
 {
    if(event->button == 1) 
@@ -212,7 +213,7 @@ static int Html_page_menu(GtkWidget *vie
  */
 static gint Html_form_new(DilloHtmlLB *html_lb,
                           DilloHtmlMethod method,
-                          const char *action,
+                          DilloURL *action,
                           DilloHtmlEnc enc)
 {
    gint nf;
@@ -222,7 +223,7 @@ static gint Html_form_new(DilloHtmlLB *h
 
    nf = html_lb->num_forms;
    html_lb->forms[nf].method = method;
-   html_lb->forms[nf].action = g_strdup(action);
+   html_lb->forms[nf].action = action;
    html_lb->forms[nf].enc = enc;
    html_lb->forms[nf].num_inputs = 0;
    html_lb->forms[nf].num_inputs_max = 4;
@@ -781,8 +782,8 @@ static void Html_tag_open_body(DilloHtml
 
    if (Html_get_attr(tag, tagsize, "bgcolor", bodycolor, sizeof(bodycolor))){
       color = a_Color_parse (bodycolor, prefs.bg_color);
-      if ( (color == 0xffffff && !prefs.allow_white_bg) ||
-           prefs.force_my_colors )
+      if ( (color == 0xffffff && !prefs.allow_white_bg) || 
+	   prefs.force_my_colors )
          color = prefs.bg_color;
 
       a_Dw_widget_set_bg_color(DW_WIDGET (page), color);
@@ -977,7 +978,8 @@ static void Html_tag_open_img(DilloHtml 
    DwPageAttr Attr;
    DwPage *page;
    gchar alt[1024], tmp[1024];
-   gchar *parsed, *url, *alt_ptr, *ptmp = tmp;
+   gchar *parsed, *alt_ptr, *ptmp = tmp;
+   DilloURL *url;
    gint AttrNum, ClientKey;
    char width_str[64], height_str[64], *width_ptr, *height_ptr;
    
@@ -985,7 +987,7 @@ static void Html_tag_open_img(DilloHtml 
       return;
    url = a_Url_resolve_relative(html->linkblock->base_url, parsed);
    g_free(parsed);
-   if ( !url ) 
+   if ( !url )
       return;
 
    page = (DwPage *)html->dw;
@@ -1109,7 +1111,8 @@ static void Html_tag_open_area(DilloHtml
    char tmp[1024];
    gint type = DW_PAGE_SHAPE_RECT;
    int nbpoints;
-   gchar *url, *parsed;
+   gchar *parsed;
+   DilloURL *url;
 
    //g_print("  Html_tag_open_area: in map %d, ", page->current_map);
    poly.map = page->current_map;
@@ -1172,7 +1175,7 @@ static void Html_tag_open_area(DilloHtml
       }
       if ((parsed = Html_get_attr_p(tag, tagsize, "href", 3)) != NULL) {
          url = a_Url_resolve_relative(html->linkblock->base_url, parsed);
-         g_free(parsed);
+	 g_free(parsed);
          if ( !url )
             return;
          if( Html_get_attr(tag, tagsize, "alt", tmp, sizeof(tmp)) )
@@ -1196,7 +1199,8 @@ static void Html_tag_open_a(DilloHtml *h
    DwPage *page;
    DwPageAttr attr;
    gchar name[512];
-   gchar *url, *parsed;
+   gchar *parsed;
+   DilloURL *url;
 
    Html_push_tag(html, tag, tagsize);
 
@@ -1205,7 +1209,7 @@ static void Html_tag_open_a(DilloHtml *h
    /* todo: add support for MAP with A HREF */
    Html_tag_open_area(html, tag, tagsize);
 
-   if ((parsed = Html_get_attr_p(tag, tagsize, "href", 3)) != NULL) {
+   if ((parsed =  Html_get_attr_p(tag, tagsize, "href", 3)) != NULL) {
       url = a_Url_resolve_relative(html->linkblock->base_url, parsed);
       g_free(parsed);
       if ( !url )
@@ -1532,7 +1536,7 @@ static void Html_tag_open_form(DilloHtml
    char method_str[80];
    char action_str[1024];
    char enc_str[80];
-   gchar *action;
+   DilloURL *action;
    DilloHtmlMethod method;
    DilloHtmlEnc enc;
 
@@ -1549,7 +1553,7 @@ static void Html_tag_open_form(DilloHtml
    if (Html_get_attr(tag, tagsize, "action", action_str, sizeof(action_str))) {
       action = a_Url_resolve_relative(html->linkblock->base_url, action_str);
    } else {
-      action = g_strdup(html->linkblock->base_url);
+      action = html->linkblock->base_url;
    }
    enc = DILLO_HTML_ENC_URLENCODING;
    if ( Html_get_attr(tag, tagsize, "encoding", enc_str, sizeof(enc_str)) ) {
@@ -1827,9 +1831,12 @@ static void Html_submit_form(GtkWidget *
    form = &html_lb->forms[i];
    if ((form->method == DILLO_HTML_METHOD_GET) ||
        (form->method == DILLO_HTML_METHOD_POST)) {
+      gchar *form_action = a_Url_to_string(form->action);
+
       GString *new_url = g_string_new("");
-      g_print("Html_submit_form form->action=%s\n", form->action);
-      g_string_append(new_url, form->action);
+      g_print("Html_submit_form form->action=%s\n", form_action);
+      g_string_append(new_url, form_action);
+      g_free(form_action);
       g_string_append_c(new_url, '?');
       if (form->method == DILLO_HTML_METHOD_POST)
          g_string_append(new_url, "!POST:");
@@ -1879,19 +1886,19 @@ static void Html_submit_form(GtkWidget *
               Html_urlencode_append(new_url,
                  gtk_entry_get_text(GTK_ENTRY(input->widget)));
               break;
-           case DILLO_HTML_INPUT_SUBMIT:
-              /* Only the button that triggered the submit. */
-              if(input->widget == submit)
-                 Html_append_input(new_url, input->name, input->init_str);
-              break;
-           default:
+	   case DILLO_HTML_INPUT_SUBMIT:
+	      /* Only the button that triggered the submit. */
+	      if(input->widget == submit)
+		 Html_append_input(new_url, input->name, input->init_str);
+	      break;
+	   default:
               break;
          } /* switch */
       } /* for (inputs) */
 
       if ( new_url->str[new_url->len - 1] == '&' )
          g_string_truncate(new_url, new_url->len - 1);
-      a_Nav_push(html_lb->bw, new_url->str);
+      a_Nav_push(html_lb->bw, a_string_to_Url(new_url->str));
       g_string_free(new_url, TRUE);
    } else {
       g_print("Method unknown\n");
@@ -1936,11 +1943,11 @@ static void Html_tag_open_input(DilloHtm
    gint input_index;
 
    if (!html->InForm)
-      return;
+       return;
 
    html_lb = html->linkblock;
    form = &(html_lb->forms[html_lb->num_forms - 1]);
-
+ 
    /* Indicate if the VALUE attribute exists. */
    has_value = Html_get_attr(tag, tagsize, "value", value, sizeof(value));
 
@@ -1949,7 +1956,7 @@ static void Html_tag_open_input(DilloHtm
 
    if (!Html_get_attr(tag, tagsize, "type", type, sizeof(type)))
       strcpy(type, "text");
-   
+
    if (!g_strcasecmp(type, "password")) {
       inp_type = DILLO_HTML_INPUT_PASSWORD;
       widget = gtk_entry_new();
@@ -2108,14 +2115,14 @@ static void Html_tag_open_isindex(DilloH
    GtkWidget *widget;
    DwWidget *embed_gtk;
    char action_str[1024], prompt[1024];
-   gchar *action;
+   DilloURL *action;
 
    html_lb = html->linkblock;
 
    if (Html_get_attr(tag, tagsize, "action", action_str, sizeof(action_str)))
       action = a_Url_resolve_relative(html->linkblock->base_url, action_str);
    else
-      action = g_strdup(html->linkblock->base_url);
+      action = html->linkblock->base_url;
    
    Html_form_new(html->linkblock, DILLO_HTML_METHOD_GET, action,
                  DILLO_HTML_ENC_URLENCODING);
@@ -2478,7 +2485,7 @@ static void Html_tag_open_base(DilloHtml
 
    if ((parsed = Html_get_attr_p(tag, tagsize, "href", 3)) != NULL) {
       g_free(html->linkblock->base_url);
-      html->linkblock->base_url = parsed;
+      html->linkblock->base_url = a_string_to_Url(parsed);
    }
 }
 
diff -pru dillo/src/html.h new/cvs/dillo.new/src/html.h
--- dillo/src/html.h	Fri Mar 16 18:53:19 2001
+++ new/cvs/dillo.new/src/html.h	Sat Mar 24 00:45:55 2001
@@ -29,7 +29,7 @@ typedef struct _DilloHtmlInput   DilloHt
 
 struct _DilloHtmlLB {
   BrowserWindow *bw;
-  char *base_url;
+  DilloURL *base_url;
 
   DilloHtmlForm *forms;
   gint num_forms;
@@ -75,7 +75,7 @@ typedef enum {
 
 struct _DilloHtmlForm {
   DilloHtmlMethod method;
-  char *action;
+  DilloURL *action;
   DilloHtmlEnc enc;
 
   DilloHtmlInput *inputs;
diff -pru dillo/src/interface.c new/cvs/dillo.new/src/interface.c
--- dillo/src/interface.c	Sun Mar  4 16:21:34 2001
+++ new/cvs/dillo.new/src/interface.c	Mon Mar  5 02:10:08 2001
@@ -229,7 +229,7 @@ void a_Interface_add_client(BrowserWindo
  * possible to stop, abort and reload them.)
  *   Flags: Chosen from {BW_Root, BW_Image, BW_Download}
  */
-void a_Interface_add_url(BrowserWindow *bw, char *Url, gint Flags)
+void a_Interface_add_url(BrowserWindow *bw, const DilloURL *Url, gint Flags)
 {
    gint nu, i;
    gboolean found = FALSE;
@@ -238,14 +238,14 @@ void a_Interface_add_url(BrowserWindow *
 
    nu = bw->NumPageUrls;
    for ( i = 0; i < nu; i++ ) {
-      if ( strcmp(Url, bw->PageUrls[i].Url) == 0 ) {
+      if ( ! a_Url_cmp(Url, bw->PageUrls[i].Url) ) {
          found = TRUE;
          break;
       }
    }
    if ( !found ) {
       a_List_add(bw->PageUrls, nu, sizeof(*bw->PageUrls), bw->MaxPageUrls);
-      bw->PageUrls[nu].Url = g_strdup(Url);
+      bw->PageUrls[nu].Url = a_Url_dup(Url);
       bw->PageUrls[nu].Flags = Flags;
       bw->NumPageUrls++;
    }
@@ -667,7 +667,7 @@ static void
        (GTK_FILE_SELECTION(bw->openfile_dialog_window));
    if (strlen(fn) + 6 <= sizeof(url)) {
       sprintf(url, "file:%s", fn);
-      a_Nav_push(bw, url);
+      a_Nav_push(bw, a_string_to_Url(url));
    }
    gtk_widget_destroy(bw->openfile_dialog_window);
 }
@@ -679,7 +679,8 @@ static void
  */
 void a_Interface_entry_open_url(GtkWidget *widget, BrowserWindow *bw)
 {
-   gchar *url, *text;
+   gchar *text;
+   DilloURL *url;
    GtkEntry *entry;
 
    /* Find which entry to get the URL from. This is a bit of a hack. */
@@ -693,7 +694,7 @@ void a_Interface_entry_open_url(GtkWidge
    g_print("entry_open_url %s\n", text);
 #endif
    if ( text && text[0] != '\0' ) {
-      url = a_Url_resolve_relative("http:/", text);
+      url = a_Url_resolve_relative(a_string_to_Url("http:/"), text);
       if ( url ) {
          a_Nav_push(bw, url);
          g_free(url);
@@ -844,14 +845,15 @@ void Interface_save_callback(int Op, Cac
  */
 void Interface_entry_save_url(GtkWidget *widget, BrowserWindow *bw)
 {
-   const char *url, *name;
+   const char *name;
+   DilloURL *url;
    GtkEntry *entry, *entry_url;
    FILE *out;
 
-   entry = GTK_ENTRY(bw->save_dialog_entry);
+   entry     = GTK_ENTRY(bw->save_dialog_entry);
    entry_url = GTK_ENTRY(bw->location);
-   name = gtk_entry_get_text(entry);
-   url  = gtk_entry_get_text(entry_url);
+   name      = gtk_entry_get_text(entry);
+   url       = a_string_to_Url(gtk_entry_get_text(entry_url));
 
    if ( strlen(name) && (out = fopen(name, "w")) != NULL ) {
       DilloWeb *Web = a_Web_new(url);
@@ -871,7 +873,8 @@ void Interface_entry_save_url(GtkWidget 
  */
 void Interface_entry_save_link(GtkWidget *widget, BrowserWindow *bw)
 {
-   const char *url, *name;
+   const char *name;
+   DilloURL *url;
    FILE *out;
 
    name = gtk_entry_get_text(GTK_ENTRY(bw->save_link_dialog_entry));
@@ -936,7 +939,9 @@ void a_Interface_save_link_dialog(GtkWid
    char *SuggestedName;   /* Suggested save name */
 
    if (!bw->save_link_dialog_window) {
-      SuggestedName = Interface_make_save_name(bw->menu_popup.info.url);
+      gchar *url = a_Url_to_string(bw->menu_popup.info.url);
+      SuggestedName = Interface_make_save_name(url);
+      g_free(url);
       Interface_make_dialog(&(bw->save_link_dialog_window),
          "save_link_dialog", "Dillo", "Dillo: Save link as file",
          &(bw->save_link_dialog_entry), SuggestedName,
diff -pru dillo/src/interface.h new/cvs/dillo.new/src/interface.h
--- dillo/src/interface.h	Sun Mar  4 16:21:34 2001
+++ new/cvs/dillo.new/src/interface.h	Mon Mar  5 01:02:09 2001
@@ -9,7 +9,7 @@ void a_Interface_clean(BrowserWindow *bw
 void a_Interface_quit_all(void);
 
 void a_Interface_add_client(BrowserWindow *bw, gint Key, gint Root);
-void a_Interface_add_url(BrowserWindow *bw, char *Url, gint Flags);
+void a_Interface_add_url(BrowserWindow *bw, const DilloURL *Url, gint Flags);
 void a_Interface_close_client(BrowserWindow *bw, gint ClientKey);
 
 void a_Interface_status(BrowserWindow *bw, const char *format, ... );
diff -pru dillo/src/nav.c new/cvs/dillo.new/src/nav.c
--- dillo/src/nav.c	Sun Mar  4 16:21:34 2001
+++ new/cvs/dillo.new/src/nav.c	Mon Mar  5 03:15:12 2001
@@ -28,6 +28,7 @@
 #include "progressbar.h"
 /*#include "dw_border.h"*/
 #include "prefs.h"
+#include "urlparse.h"
 
 /* Support for a navigation stack */
 
@@ -54,34 +55,36 @@ void a_Nav_init(BrowserWindow *bw)
  * Set 'ForceReload' to TRUE to bypass the reload check.
  */
 static void
- Nav_open_url(BrowserWindow *bw, const char *Url, gboolean ForceReload)
+ Nav_open_url(BrowserWindow *bw, const DilloURL *Url, gboolean ForceReload)
 {
-   char *url, *hash, *anchor, *old_url;
+   char *url, *hash, *anchor;
+   DilloURL *old_Url;
    gboolean MustLoad;
    gint ClientKey;
    DilloWeb *web;
 
-   url = g_strdup(Url);
+   /*   url = g_strdup(Url); */
+   url = a_Url_to_string(Url);
    anchor = NULL;
-   if ( (hash = a_Url_parse_hash(url)) != NULL ) {
+   if ( (hash = a_Url_parse_hash(Url)) != NULL ) {
       *hash = '\0';
       anchor = hash + 1;
    }
 
    /* Get the url of the current page */
-   old_url = NULL;
+   old_Url = NULL;
    if ( bw->nav_expecting ) {
       if ( bw->nav_stack_ptr != -1 )
-         old_url = g_strdup(bw->nav_stack[bw->nav_stack_ptr].url);
+         old_Url = bw->nav_stack[bw->nav_stack_ptr].url;
    } else {
       if ( bw->nav_expect.url )
-         old_url = g_strdup(bw->nav_expect.url);
+         old_Url = bw->nav_expect.url;
    }
-   if ( old_url && (hash = a_Url_parse_hash(old_url)) != NULL )
+   if ( old_Url && (hash = a_Url_parse_hash(old_Url)) != NULL )
       *hash = '\0';
 
    /* Page must be reloaded, if old and new url (without anchor) differ */
-   MustLoad = ForceReload || !(old_url && strcmp(old_url, url) == 0);
+   MustLoad = ForceReload || !(old_Url && !a_Url_cmp(old_Url, Url));
    if ( MustLoad ) {
       a_Dw_gtk_scrolled_window_queue_anchor
          (GTK_DW_SCROLLED_WINDOW(bw->docwin), anchor);
@@ -92,18 +95,18 @@ static void
 
       if ( bw->nav_expecting == FALSE )
          gtk_entry_set_text(GTK_ENTRY(bw->location),
-                            bw->nav_stack[bw->nav_stack_ptr].url);
+                            bw->nav_stack[bw->nav_stack_ptr].url->original_url);
 
-      web = a_Web_new(url);
+      web = a_Web_new(Url);
       web->bw = bw;
       web->flags |= WEB_RootUrl;
 
       g_print("Nav_open_url: Url=>%s<\n", url);
 
       a_Menu_pagemarks_new(web->bw);
-      ClientKey = a_Cache_open_url(url, NULL, web);
+      ClientKey = a_Cache_open_url(Url, NULL, web);
       a_Interface_add_client(bw, ClientKey, 1);
-      a_Interface_add_url(bw, url, WEB_RootUrl);
+      a_Interface_add_url(bw, Url, WEB_RootUrl);
       a_Interface_set_cursor(bw, GDK_LEFT_PTR);
    } else {
       /* Don't reload the page, jump directly to the #anchor position */
@@ -113,7 +116,7 @@ static void
    }
 
    g_free(url);
-   if (old_url) g_free (old_url);
+   /*   if (old_Url) g_free (old_Url); */
 }
 
 /*
@@ -161,7 +164,7 @@ void a_Nav_expect_done(BrowserWindow *bw
 
    //g_print("a_Nav_expect_done: Url=>%s<\n", bw->nav_expect.url);
 
-   gtk_entry_set_text(GTK_ENTRY(bw->location), bw->nav_expect.url);
+   gtk_entry_set_text(GTK_ENTRY(bw->location), bw->nav_expect.url->original_url);
    bw->nav_stack[i].url = bw->nav_expect.url;
    bw->nav_stack[i].title = bw->nav_expect.title;
    bw->nav_expect.url = NULL;
@@ -175,7 +178,7 @@ void a_Nav_expect_done(BrowserWindow *bw
  * Remove top-URL from the navigation stack.
  * (Used to remove URLs that force redirection)
  */
-void a_Nav_remove_top_url(BrowserWindow *bw, const char *url)
+void a_Nav_remove_top_url(BrowserWindow *bw, const DilloURL *url)
 {
    if (!bw || !url)
       return;
@@ -202,18 +205,18 @@ void a_Nav_remove_top_url(BrowserWindow 
  * - Set bw to expect the URL data
  * - Ask the cache to feed back the requested URL (via Nav_open_url)
  */
-void a_Nav_push(BrowserWindow *bw, const char *Url)
+void a_Nav_push(BrowserWindow *bw, const DilloURL *Url)
 {
    char *p, *url;
 
    g_return_if_fail (bw != NULL);
 
-   url = g_strdup(Url);
+   url = a_Url_to_string(Url);
    if ( (p = strstr(url, "?!POST")) != NULL )
       *p = '\0';
 
    a_Nav_cancel_expect(bw);
-   bw->nav_expect.url = g_strdup(url);
+   bw->nav_expect.url = a_string_to_Url(url);
    bw->nav_expect.title = NULL;
    bw->nav_expecting = TRUE;
    Nav_open_url(bw, Url, FALSE);
@@ -223,7 +226,7 @@ void a_Nav_push(BrowserWindow *bw, const
 /*
  * Wraps a_Nav_push to match 'DwPage->link' function type
  */
-void a_Nav_vpush(void *vbw, const char *url)
+void a_Nav_vpush(void *vbw, DilloURL *url)
 {
    a_Nav_push(vbw, url);
 }
@@ -257,7 +260,7 @@ void a_Nav_forw(BrowserWindow *bw)
  */
 void a_Nav_home(BrowserWindow *bw)
 {
-   a_Nav_push(bw, prefs.home);
+   a_Nav_push(bw, a_string_to_Url(prefs.home));
 }
 
 /*
diff -pru dillo/src/nav.h new/cvs/dillo.new/src/nav.h
--- dillo/src/nav.h	Sun Mar  4 16:21:34 2001
+++ new/cvs/dillo.new/src/nav.h	Sun Mar  4 01:43:04 2001
@@ -1,12 +1,13 @@
 #ifndef __DILLO_NAV_H__
 #define __DILLO_NAV_H__
 
+#include "urlparse.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
 
-void a_Nav_push(BrowserWindow *bw, const char*);
+void a_Nav_push(BrowserWindow *bw, const DilloURL* Url);
 void a_Nav_vpush(void *vbw, const char *url);
 void a_Nav_back(BrowserWindow *bw);
 void a_Nav_forw(BrowserWindow *bw);
@@ -15,7 +16,7 @@ void a_Nav_reload(BrowserWindow *bw);
 void a_Nav_init(BrowserWindow *bw);
 void a_Nav_cancel_expect (BrowserWindow *bw);
 void a_Nav_expect_done(BrowserWindow *bw, DwWidget *dw);
-void a_Nav_remove_top_url(BrowserWindow *bw, const char *url);
+void a_Nav_remove_top_url(BrowserWindow *bw, const DilloURL *url);
 
 
 #ifdef __cplusplus
diff -pru dillo/src/png.c new/cvs/dillo.new/src/png.c
--- dillo/src/png.c	Wed Mar  7 16:38:13 2001
+++ new/cvs/dillo.new/src/png.c	Sat Mar 24 00:48:51 2001
@@ -357,7 +357,7 @@ void Png_callback(int Op, CacheClient_t 
                            (png_error_ptr)Png_error_handling);
          g_return_if_fail (png->png_ptr != NULL);
          png->info_ptr = png_create_info_struct(png->png_ptr);
-         g_return_if_fail (png->info_ptr != NULL);
+	 g_return_if_fail (png->info_ptr != NULL);
 
          setjmp(png->jmpbuf);
          if(!png->error) {
Only in new/cvs/dillo.new/src: urlparse.c
Only in new/cvs/dillo.new/src: urlparse.c~
Only in new/cvs/dillo.new/src: urlparse.h
Only in new/cvs/dillo.new/src: urlparse.h~
diff -pru dillo/src/web.c new/cvs/dillo.new/src/web.c
--- dillo/src/web.c	Sun Mar  4 16:21:34 2001
+++ new/cvs/dillo.new/src/web.c	Mon Mar  5 00:50:10 2001
@@ -56,7 +56,7 @@ DwWidget* a_Web_dispatch_by_type (const 
    if ( Web->url && Web->linkblock ) {
       if ( Web->linkblock->base_url )
          g_free(Web->linkblock->base_url);
-      Web->linkblock->base_url = g_strdup(Web->url);
+      Web->linkblock->base_url = Web->url;
    }
 
    if ( Web->bw->nav_expecting )
@@ -79,11 +79,11 @@ void a_Web_free(DilloWeb *web)
 /*
  * Allocate and set safe values for a DilloWeb structure
  */
-DilloWeb* a_Web_new(const char *url)
+DilloWeb* a_Web_new(const DilloURL *url)
 {
    DilloWeb *web= g_new(DilloWeb, 1);
 
-   web->url = g_strdup(url);
+   web->url = a_Url_dup(url);
 
    web->bw = NULL;
    web->dw = NULL;
diff -pru dillo/src/web.h new/cvs/dillo.new/src/web.h
--- dillo/src/web.h	Sun Mar  4 16:21:34 2001
+++ new/cvs/dillo.new/src/web.h	Mon Mar  5 00:49:50 2001
@@ -12,6 +12,7 @@ typedef struct _DilloWeb DilloWeb;
 /*#include "dw_gtk_scroller.h"*/
 #include "cache.h"
 #include "html.h"
+#include "urlparse.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -26,7 +27,7 @@ extern "C" {
 
 
 struct _DilloWeb {
-  char *url;                  /* Requested URL */
+  DilloURL *url;              /* Requested URL */
   BrowserWindow *bw;          /* The requesting browser window */
   DwWidget *dw;               /* Dillo widget for 'url' */
   DilloHtmlLB *linkblock;     /* HTML linkblock reference */
@@ -38,7 +39,7 @@ struct _DilloWeb {
 };
 
 
-DilloWeb* a_Web_new (const char* url);
+DilloWeb* a_Web_new (const DilloURL* url);
 void a_Web_free (DilloWeb*);
 DwWidget* a_Web_dispatch_by_type (const char *Type, DilloWeb *web,
                                   CA_Callback_t *Call, void **Data);

