diff options
author | Dan Winship <danw@src.gnome.org> | 2000-04-06 11:52:39 +0800 |
---|---|---|
committer | Dan Winship <danw@src.gnome.org> | 2000-04-06 11:52:39 +0800 |
commit | 2e4a5463075e387151afcdf61b74202a729944db (patch) | |
tree | 451716a6b189f11de18346a86716cbedf010f609 /camel/camel-url.c | |
parent | 080049ac37387efd71551bfdb661e15c0e1ce8ce (diff) | |
download | gsoc2013-evolution-2e4a5463075e387151afcdf61b74202a729944db.tar gsoc2013-evolution-2e4a5463075e387151afcdf61b74202a729944db.tar.gz gsoc2013-evolution-2e4a5463075e387151afcdf61b74202a729944db.tar.bz2 gsoc2013-evolution-2e4a5463075e387151afcdf61b74202a729944db.tar.lz gsoc2013-evolution-2e4a5463075e387151afcdf61b74202a729944db.tar.xz gsoc2013-evolution-2e4a5463075e387151afcdf61b74202a729944db.tar.zst gsoc2013-evolution-2e4a5463075e387151afcdf61b74202a729944db.zip |
the URL RFC says the port must be numeric, so we don't want to do
* g_url_new really wanted to take a CamelException. So, rename
Gurl to CamelURL, g_url_* to camel_url_* (with camel_url_new
taking an exception), and url-util.[ch] to camel-url.[ch]. Also
force url->port to be numeric and remove camel_service_getport. (I
was confused before: the URL RFC says the port must be numeric, so
we don't want to do getportbyname.)
svn path=/trunk/; revision=2300
Diffstat (limited to 'camel/camel-url.c')
-rw-r--r-- | camel/camel-url.c | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/camel/camel-url.c b/camel/camel-url.c new file mode 100644 index 0000000000..8372ae7031 --- /dev/null +++ b/camel/camel-url.c @@ -0,0 +1,188 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* camel-url.c : utility functions to parse URLs */ + + +/* + * Authors: + * Bertrand Guiheneuf <bertrand@helixcode.com> + * Dan Winship <danw@helixcode.com> + * + * Copyright 1999, 2000 Helix Code, Inc. (http://www.helixcode.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + + +/* XXX TODO: + * recover the words between #'s or ?'s after the path + * % escapes + */ + +#include <config.h> +#include <stdlib.h> +#include <string.h> +#include "camel-url.h" +#include "camel-exception.h" + +/** + * camel_url_new: create a CamelURL object from a string + * @url_string: The string containing the URL to scan + * + * This routine takes a string and parses it as a URL of the form: + * + * protocol://user;AUTH=mech:password@host:port/path + * + * The protocol, followed by a ":" is required. If it is followed by + * "//", there must be an "authority" containing at least a host, + * which ends at the end of the string or at the next "/". If there + * is an "@" in the authority, there must be a username before it, + * and the host comes after it. The authmech, password, and port are + * optional, and the punctuation that preceeds them is omitted if + * they are. Everything after the authority (or everything after the + * protocol if there was no authority) is the path. We consider the + * "/" between the authority and the path to be part of the path, + * although this is incorrect according to RFC 1738. + * + * The port, if present, must be numeric. + * + * Return value: a CamelURL structure containing the URL items. + **/ +CamelURL * +camel_url_new (const char *url_string, CamelException *ex) +{ + CamelURL *url; + char *semi, *colon, *at, *slash; + + /* Find protocol: initial substring until ":" */ + colon = strchr (url_string, ':'); + if (!colon) { + camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_URL_INVALID, + "URL string `%s' contains no protocol", + url_string); + return NULL; + } + + url = g_new0 (CamelURL, 1); + url->protocol = g_strndup (url_string, colon - url_string); + + if (strncmp (colon, "://", 3) != 0) { + if (*(colon + 1)) + url->path = g_strdup (colon + 1); + return url; + } + + url_string = colon + 3; + + /* If there is an @ sign in the authority, look for user, + * authmech, and password before it. + */ + slash = strchr (url_string, '/'); + at = strchr (url_string, '@'); + if (at && (!slash || at < slash)) { + colon = strchr (url_string, ':'); + if (colon && colon < at) + url->passwd = g_strndup (colon + 1, at - colon - 1); + else { + url->passwd = NULL; + colon = at; + } + + semi = strchr(url_string, ';'); + if (semi && (semi < colon || (!colon && semi < at)) && + !strncasecmp (semi, ";auth=", 6)) { + url->authmech = g_strndup (semi + 6, + colon - semi - 6); + } else { + url->authmech = NULL; + semi = colon; + } + + url->user = g_strndup (url_string, semi - url_string); + url_string = at + 1; + } else + url->user = url->passwd = url->authmech = NULL; + + /* Find host and port. */ + slash = strchr (url_string, '/'); + colon = strchr (url_string, ':'); + if (slash && colon > slash) + colon = NULL; + + if (colon) { + url->host = g_strndup (url_string, colon - url_string); + url->port = strtoul (colon + 1, &colon, 10); + if (*colon && colon != slash) { + camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_URL_INVALID, + "Port number in URL `%s' is non-" + "numeric", url_string); + camel_url_free (url); + return NULL; + } + } else if (slash) { + url->host = g_strndup (url_string, slash - url_string); + url->port = 0; + } else { + url->host = g_strdup (url_string); + url->port = 0; + } + + if (!slash) + slash = "/"; + url->path = g_strdup (slash); + + return url; +} + +char * +camel_url_to_string (CamelURL *url, gboolean show_passwd) +{ + char port[20]; + + if (url->port) + g_snprintf (port, sizeof (port), "%d", url->port); + else + *port = '\0'; + + return g_strdup_printf ("%s:%s%s%s%s%s%s%s%s%s%s%s", + url->protocol, + url->host ? "//" : "", + url->user ? url->user : "", + url->authmech ? ";auth=" : "", + url->authmech ? url->authmech : "", + url->passwd && show_passwd ? ":" : "", + url->passwd && show_passwd ? url->passwd : "", + url->user ? "@" : "", + url->host ? url->host : "", + url->port ? ":" : "", + port, + url->path ? url->path : ""); +} + +void +camel_url_free (CamelURL *url) +{ + g_assert (url); + + g_free (url->protocol); + g_free (url->user); + g_free (url->authmech); + g_free (url->passwd); + g_free (url->host); + g_free (url->path); + + g_free (url); +} |