diff options
-rw-r--r-- | e-util/ChangeLog | 7 | ||||
-rw-r--r-- | e-util/Makefile.am | 1 | ||||
-rw-r--r-- | e-util/e-url.c | 177 | ||||
-rw-r--r-- | e-util/e-url.h | 18 |
4 files changed, 203 insertions, 0 deletions
diff --git a/e-util/ChangeLog b/e-util/ChangeLog index 39ecbff390..310364031f 100644 --- a/e-util/ChangeLog +++ b/e-util/ChangeLog @@ -1,3 +1,10 @@ +2001-10-01 Rodrigo Moya <rodrigo@ximian.com> + + * e-url.[ch]: added basic URI management functions + + * Makefile.am: added BONOBO flags to make it compile with latest + Bonobo, which installs headers in a version-based directory + 2001-10-01 Dan Winship <danw@ximian.com> * e-passwords.c (e_passwords_ask_password): New, copied/renamed diff --git a/e-util/Makefile.am b/e-util/Makefile.am index 04e780e120..f0dbca7500 100644 --- a/e-util/Makefile.am +++ b/e-util/Makefile.am @@ -7,6 +7,7 @@ INCLUDES = \ -I$(top_srcdir) \ $(GNOME_INCLUDEDIR) \ $(EXTRA_GNOME_CFLAGS) \ + $(BONOBO_GNOME_CFLAGS) \ $(BONOBO_CONF_CFLAGS) \ $(PISOCK_CFLAGS) \ -DEVOLUTION_IMAGES=\""$(imagesdir)"\" \ diff --git a/e-util/e-url.c b/e-util/e-url.c index 8b54a81d16..ae37c71a74 100644 --- a/e-util/e-url.c +++ b/e-util/e-url.c @@ -6,6 +6,7 @@ * Copyright (C) 2001 Ximian, Inc. * * Developed by Jon Trowbridge <trow@ximian.com> + * Rodrigo Moya <rodrigo@ximian.com> */ /* @@ -26,6 +27,7 @@ */ #include <config.h> +#include <ctype.h> #include <string.h> #include "e-url.h" @@ -84,3 +86,178 @@ e_url_equal (const char *url1, const char *url2) return rv; } + +#define HEXVAL(c) (isdigit (c) ? (c) - '0' : tolower (c) - 'a' + 10) + +static void +uri_decode (char *part) +{ + guchar *s, *d; + + s = d = (guchar *)part; + while (*s) { + if (*s == '%') { + if (isxdigit (s[1]) && isxdigit (s[2])) { + *d++ = HEXVAL (s[1]) * 16 + HEXVAL (s[2]); + s += 3; + } else + *d++ = *s++; + } else + *d++ = *s++; + } + *d = '\0'; +} + +EUri * +e_uri_new (const char *uri_string) +{ + EUri *uri; + const char *end, *hash, *colon, *semi, *at, *slash, *question; + const char *p; + + uri = g_new0 (EUri, 1); + + /* find fragment */ + end = hash = strchr (uri_string, '#'); + if (hash && hash[1]) { + uri->fragment = g_strdup (hash + 1); + uri_decode (uri->fragment); + } + else + end = uri_string + strlen (uri_string); + + /* find protocol: initial [a-z+.-]* substring until ":" */ + p = uri_string; + while (p < end && (isalnum ((unsigned char) *p) || + *p == '.' || *p == '+' || *p == '-')) + p++; + + if (p > uri_string && *p == ':') { + uri->protocol = g_strndup (uri_string, p - uri_string); + g_strdown (uri->protocol); + uri_string = p + 1; + } + + if (!*uri_string) + return uri; + + /* check for authority */ + 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; + } + 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); + } + else { + uri->host = g_strndup (uri_string, slash - uri_string); + uri_decode (uri->host); + uri->port = 0; + } + + uri_string = slash; + } + + /* 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 parameters */ + semi = memchr (uri_string, ';', end - uri_string); + if (semi) { + if (semi[1]) { + const char *cur, *p, *eq; + char *name, *value; + + for (cur = semi + 1; cur < end; cur = p + 1) { + p = memchr (cur, ';', end - cur); + if (!p) + p = end; + eq = memchr (cur, '=', p - cur); + if (eq) { + name = g_strndup (cur, eq - cur); + value = g_strndup (eq + 1, p - (eq + 1)); + uri_decode (value); + } else { + name = g_strndup (cur, p - cur); + value = g_strdup (""); + } + uri_decode (name); + g_datalist_set_data_full (&uri->params, name, + value, g_free); + g_free (name); + } + } + end = semi; + } + + if (end != uri_string) { + uri->path = g_strndup (uri_string, end - uri_string); + uri_decode (uri->path); + } + + return uri; +} + +void +e_uri_free (EUri *uri) +{ + if (uri) { + g_free (uri->protocol); + g_free (uri->user); + g_free (uri->authmech); + g_free (uri->passwd); + g_free (uri->host); + g_free (uri->path); + g_datalist_clear (&uri->params); + g_free (uri->query); + g_free (uri->fragment); + + g_free (uri); + } +} + +const char * +e_uri_get_param (EUri *uri, const char *name) +{ + return g_datalist_get_data (&uri->params, name); +} diff --git a/e-util/e-url.h b/e-util/e-url.h index 5250963dba..de24554d9b 100644 --- a/e-util/e-url.h +++ b/e-util/e-url.h @@ -6,6 +6,7 @@ * Copyright (C) 2001 Ximian, Inc. * * Developed by Jon Trowbridge <trow@ximian.com> + * Rodrigo Moya <rodrigo@ximian.com> */ /* @@ -33,5 +34,22 @@ char *e_url_shroud (const char *url); gboolean e_url_equal (const char *url1, const char *url2); +typedef struct { + char *protocol; + char *user; + char *authmech; + char *passwd; + char *host; + int port; + char *path; + GData *params; + char *query; + char *fragment; +} EUri; + +EUri *e_uri_new (const char *uri_string); +void e_uri_free (EUri *uri); +const char *e_uri_get_param (EUri *uri, const char *name); + #endif /* __E_URL_H__ */ |