aboutsummaryrefslogtreecommitdiffstats
path: root/camel/camel-url.c
diff options
context:
space:
mode:
authorDan Winship <danw@src.gnome.org>2000-04-06 11:52:39 +0800
committerDan Winship <danw@src.gnome.org>2000-04-06 11:52:39 +0800
commit2e4a5463075e387151afcdf61b74202a729944db (patch)
tree451716a6b189f11de18346a86716cbedf010f609 /camel/camel-url.c
parent080049ac37387efd71551bfdb661e15c0e1ce8ce (diff)
downloadgsoc2013-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.c188
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);
+}