aboutsummaryrefslogtreecommitdiffstats
path: root/camel
diff options
context:
space:
mode:
Diffstat (limited to 'camel')
-rw-r--r--camel/ChangeLog9
-rw-r--r--camel/Makefile.am4
-rw-r--r--camel/camel-service.c76
-rw-r--r--camel/camel-service.h14
-rw-r--r--camel/camel-session.c18
-rw-r--r--camel/camel-url.c188
-rw-r--r--camel/camel-url.h (renamed from camel/url-util.h)43
-rw-r--r--camel/camel.h2
-rw-r--r--camel/providers/mbox/camel-mbox-store.c4
-rw-r--r--camel/providers/pop3/camel-pop3-store.c9
-rw-r--r--camel/url-util.c172
11 files changed, 255 insertions, 284 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index 155bc3fb0f..28bc79c521 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,3 +1,12 @@
+2000-04-05 Dan Winship <danw@helixcode.com>
+
+ * 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.)
+
2000-04-01 Dan Winship <danw@helixcode.com>
* providers/mbox/camel-mbox-folder.c
diff --git a/camel/Makefile.am b/camel/Makefile.am
index 6e5f346b60..eefc48bd10 100644
--- a/camel/Makefile.am
+++ b/camel/Makefile.am
@@ -64,6 +64,7 @@ libcamel_la_SOURCES = \
camel-stream-fs.c \
camel-stream-mem.c \
camel-transport.c \
+ camel-url.c \
data-wrapper-repository.c \
gmime-base64.c \
gmime-content-field.c \
@@ -72,7 +73,6 @@ libcamel_la_SOURCES = \
hash-table-utils.c \
md5-utils.c \
string-utils.c \
- url-util.c \
$(pthread_SRC)
libcamelinclude_HEADERS = \
@@ -108,6 +108,7 @@ libcamelinclude_HEADERS = \
camel-stream-fs.h \
camel-stream-mem.h \
camel-transport.h \
+ camel-url.h \
data-wrapper-repository.h \
gmime-base64.h \
gmime-content-field.h \
@@ -116,7 +117,6 @@ libcamelinclude_HEADERS = \
hash-table-utils.h \
md5-utils.h \
string-utils.h \
- url-util.h \
camel-exception-list.def \
$(pthread_HDR)
diff --git a/camel/camel-service.c b/camel/camel-service.c
index b9ed7e5c96..82b2b0ee53 100644
--- a/camel/camel-service.c
+++ b/camel/camel-service.c
@@ -37,14 +37,14 @@ static GtkObjectClass *parent_class=NULL;
#define CSERV_CLASS(so) CAMEL_SERVICE_CLASS (GTK_OBJECT(so)->klass)
static gboolean _connect(CamelService *service, CamelException *ex);
-static gboolean _connect_with_url (CamelService *service, Gurl *url,
+static gboolean _connect_with_url (CamelService *service, CamelURL *url,
CamelException *ex);
static gboolean _disconnect(CamelService *service, CamelException *ex);
static gboolean _is_connected (CamelService *service);
static GList * _query_auth_types (CamelService *service);
static void _free_auth_types (CamelService *service, GList *authtypes);
static void _finalize (GtkObject *object);
-static gboolean _set_url (CamelService *service, Gurl *url,
+static gboolean _set_url (CamelService *service, CamelURL *url,
CamelException *ex);
static void
@@ -101,7 +101,7 @@ _finalize (GtkObject *object)
CAMEL_LOG_FULL_DEBUG ("Entering CamelService::finalize\n");
if (camel_service->url)
- g_url_free (camel_service->url);
+ camel_url_free (camel_service->url);
if (camel_service->session)
gtk_object_unref (GTK_OBJECT (camel_service->session));
@@ -123,7 +123,7 @@ _finalize (GtkObject *object)
* Return value: the CamelService, or NULL.
**/
CamelService *
-camel_service_new (GtkType type, CamelSession *session, Gurl *url,
+camel_service_new (GtkType type, CamelSession *session, CamelURL *url,
CamelException *ex)
{
CamelService *service;
@@ -197,7 +197,7 @@ camel_service_connect (CamelService *service, CamelException *ex)
* Return value: whether or not the connection succeeded
**/
static gboolean
-_connect_with_url (CamelService *service, Gurl *url, CamelException *ex)
+_connect_with_url (CamelService *service, CamelURL *url, CamelException *ex)
{
g_assert (service->session);
@@ -219,11 +219,14 @@ _connect_with_url (CamelService *service, Gurl *url, CamelException *ex)
* Return value: whether or not the connection succeeded
**/
gboolean
-camel_service_connect_with_url (CamelService *service, char *url,
+camel_service_connect_with_url (CamelService *service, char *url_string,
CamelException *ex)
{
- return CSERV_CLASS(service)->connect_with_url (service, g_url_new(url),
- ex);
+ CamelURL *url = camel_url_new (url_string, ex);
+
+ if (!url)
+ return FALSE;
+ return CSERV_CLASS(service)->connect_with_url (service, url, ex);
}
@@ -298,19 +301,19 @@ camel_service_is_connected (CamelService *service)
* @url_string: the URL
* @ex: a CamelException
*
- * This converts the URL to a Gurl, validates it for the service,
+ * This converts the URL to a CamelURL, validates it for the service,
* and sets it as the default URL for the service.
*
* Return value: success or failure
**/
static gboolean
-_set_url (CamelService *service, Gurl *url, CamelException *ex)
+_set_url (CamelService *service, CamelURL *url, CamelException *ex)
{
char *url_string;
if (service->url_flags & CAMEL_SERVICE_URL_NEED_USER &&
(url->user == NULL || url->user[0] == '\0')) {
- url_string = g_url_to_string (url, FALSE);
+ url_string = camel_url_to_string (url, FALSE);
camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_URL_INVALID,
"URL '%s' needs a username component",
url_string);
@@ -318,7 +321,7 @@ _set_url (CamelService *service, Gurl *url, CamelException *ex)
return FALSE;
} else if (service->url_flags & CAMEL_SERVICE_URL_NEED_HOST &&
(url->host == NULL || url->host[0] == '\0')) {
- url_string = g_url_to_string (url, FALSE);
+ url_string = camel_url_to_string (url, FALSE);
camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_URL_INVALID,
"URL '%s' needs a host component",
url_string);
@@ -326,7 +329,7 @@ _set_url (CamelService *service, Gurl *url, CamelException *ex)
return FALSE;
} else if (service->url_flags & CAMEL_SERVICE_URL_NEED_PATH &&
(url->path == NULL || url->path[0] == '\0')) {
- url_string = g_url_to_string (url, FALSE);
+ url_string = camel_url_to_string (url, FALSE);
camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_URL_INVALID,
"URL '%s' needs a path component",
url_string);
@@ -335,7 +338,7 @@ _set_url (CamelService *service, Gurl *url, CamelException *ex)
}
if (service->url)
- g_url_free (service->url);
+ camel_url_free (service->url);
service->url = url;
return TRUE;
}
@@ -353,7 +356,7 @@ _set_url (CamelService *service, Gurl *url, CamelException *ex)
char *
camel_service_get_url (CamelService *service)
{
- return g_url_to_string(service->url, FALSE);
+ return camel_url_to_string(service->url, FALSE);
}
@@ -463,46 +466,3 @@ camel_service_gethost (CamelService *service, CamelException *ex)
return h;
}
-
-/**
- * camel_service_getport: get the port number for a service's URL
- * @service: a CamelService
- * @default_name: the default service name if none is provided by the URL
- * @default_number: the default port number if the @default_name lookup fails
- * @proto: the protocol (eg, "tcp") to be used
- * @ex: a CamelExcption
- *
- * This is a convenience function to get the port number for a service
- * based on the service's URL (which may contain either a numeric
- * or symbolic port name) and the provided defaults.
- *
- * Return value: a port number (in network byte order), or -1 if the
- * user specified a port name that could not be resolved.
- **/
-int
-camel_service_getport (CamelService *service, char *default_port,
- int default_number, char *proto, CamelException *ex)
-{
- struct servent *s;
- char *port;
-
- if (service->url->port)
- port = service->url->port;
- else
- port = default_port;
-
- if (isdigit (*port))
- return htons (atoi (port));
-
- s = getservbyname (port, proto);
- if (s)
- return s->s_port;
-
-
- if (port == service->url->port) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_URL_INVALID,
- "Unknown port `%s'", port);
- return -1;
- } else
- return htons (default_number);
-}
diff --git a/camel/camel-service.h b/camel/camel-service.h
index 2da9c57f69..7b04ef24a8 100644
--- a/camel/camel-service.h
+++ b/camel/camel-service.h
@@ -37,7 +37,7 @@ extern "C" {
#include <gtk/gtk.h>
#include <netdb.h>
#include "camel-types.h"
-#include "url-util.h"
+#include "camel-url.h"
#define CAMEL_SERVICE_TYPE (camel_service_get_type ())
#define CAMEL_SERVICE(obj) (GTK_CHECK_CAST((obj), CAMEL_SERVICE_TYPE, CamelService))
@@ -51,7 +51,7 @@ struct _CamelService {
CamelSession *session;
gboolean connected;
- Gurl *url;
+ CamelURL *url;
int url_flags;
};
@@ -64,7 +64,7 @@ typedef struct {
gboolean (*connect) (CamelService *service,
CamelException *ex);
gboolean (*connect_with_url) (CamelService *service,
- Gurl *url,
+ CamelURL *url,
CamelException *ex);
gboolean (*disconnect) (CamelService *service,
CamelException *ex);
@@ -96,7 +96,7 @@ typedef struct {
/* public methods */
CamelService * camel_service_new (GtkType type,
CamelSession *session,
- Gurl *url,
+ CamelURL *url,
CamelException *ex);
gboolean camel_service_connect (CamelService *service,
@@ -118,11 +118,7 @@ void camel_service_free_auth_types (CamelService *service,
/* convenience functions */
struct hostent * camel_service_gethost (CamelService *service,
CamelException *ex);
-int camel_service_getport (CamelService *service,
- char *default_name,
- int default_number,
- char *proto,
- CamelException *ex);
+
/* Standard Gtk function */
GtkType camel_service_get_type (void);
diff --git a/camel/camel-session.c b/camel/camel-session.c
index 1667651fa3..6cf8da12d5 100644
--- a/camel/camel-session.c
+++ b/camel/camel-session.c
@@ -33,7 +33,7 @@
#include "camel-transport.h"
#include "camel-exception.h"
#include "string-utils.h"
-#include "url-util.h"
+#include "camel-url.h"
#include "hash-table-utils.h"
@@ -108,7 +108,7 @@ camel_session_new (CamelAuthCallback authenticator)
* @provider: provider object
*
* Set the default implementation for a protocol. The protocol
- * is determined by provider->protocol field (See CamelProtocol).
+ * is determined by provider->protocol field (See CamelProvider).
* It overrides the default provider for this protocol.
*
**/
@@ -170,7 +170,7 @@ camel_session_get_store_from_provider (CamelSession *session,
**/
static CamelStore *
get_store_for_protocol_with_url (CamelSession *session, const char *protocol,
- Gurl *url, CamelException *ex)
+ CamelURL *url, CamelException *ex)
{
const CamelProvider *provider = NULL;
@@ -235,21 +235,17 @@ CamelStore *
camel_session_get_store (CamelSession *session, const char *url_string,
CamelException *ex)
{
- Gurl *url;
+ CamelURL *url;
CamelStore *store;
- url = g_url_new (url_string);
- if (url == NULL || url->protocol == NULL) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_SERVICE_URL_INVALID,
- "Could not determine protocol for "
- "URL '%s'", url_string);
+ url = camel_url_new (url_string, ex);
+ if (!url)
return NULL;
- }
store = get_store_for_protocol_with_url (session, url->protocol,
url, ex);
if (store == NULL)
- g_url_free (url);
+ camel_url_free (url);
return store;
}
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);
+}
diff --git a/camel/url-util.h b/camel/camel-url.h
index 86fd1e26ac..6b7d32aef1 100644
--- a/camel/url-util.h
+++ b/camel/camel-url.h
@@ -1,11 +1,12 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* url-util.h : utility functions to parse URLs */
+/* camel-url.h : utility functions to parse URLs */
/*
- * Author :
+ * Authors:
* Bertrand Guiheneuf <bertrand@helixcode.com>
+ * Dan Winship <danw@helixcode.com>
*
- * Copyright 1999, 2000 HelixCode (http://www.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
@@ -24,10 +25,11 @@
*/
-#ifndef URL_UTIL_H
-#define URL_UTIL_H 1
+#ifndef CAMEL_URL_H
+#define CAMEL_URL_H 1
#include <glib.h>
+#include "camel-types.h"
#ifdef __cplusplus
extern "C" {
@@ -35,24 +37,19 @@ extern "C" {
#endif /* __cplusplus */
typedef struct {
- gchar *protocol;
- gchar *user;
- gchar *authmech;
- gchar *passwd;
- gchar *host;
- gchar *port;
- gchar *path;
-
-} Gurl;
-
-/* the cache system has been disabled because it would
- need the user to use accessors instead of modifying the
- structure field. As the speed is not so important here,
- I chose not to use it */
-
-Gurl *g_url_new (const gchar *url_string);
-gchar *g_url_to_string (const Gurl *url, gboolean show_password);
-void g_url_free (Gurl *url);
+ char *protocol;
+ char *user;
+ char *authmech;
+ char *passwd;
+ char *host;
+ int port;
+ char *path;
+
+} CamelURL;
+
+CamelURL *camel_url_new (const char *url_string, CamelException *ex);
+char *camel_url_to_string (CamelURL *url, gboolean show_password);
+void camel_url_free (CamelURL *url);
#ifdef __cplusplus
}
diff --git a/camel/camel.h b/camel/camel.h
index 5145b58348..a92d69e04d 100644
--- a/camel/camel.h
+++ b/camel/camel.h
@@ -57,12 +57,12 @@ extern "C" {
#include <camel/camel-stream-fs.h>
#include <camel/camel-stream-mem.h>
#include <camel/camel-thread-proxy.h>
+#include <camel/camel-url.h>
#include <camel/data-wrapper-repository.h>
#include <camel/gmime-content-field.h>
#include <camel/gmime-utils.h>
#include <camel/gstring-util.h>
#include <camel/string-utils.h>
-#include <camel/url-util.h>
gint camel_init (void);
diff --git a/camel/providers/mbox/camel-mbox-store.c b/camel/providers/mbox/camel-mbox-store.c
index 74ea8c3461..32d25becf1 100644
--- a/camel/providers/mbox/camel-mbox-store.c
+++ b/camel/providers/mbox/camel-mbox-store.c
@@ -28,7 +28,7 @@
#include "camel-mbox-store.h"
#include "camel-mbox-folder.h"
#include "camel-exception.h"
-#include "url-util.h"
+#include "camel-url.h"
/* Returns the class for a CamelMboxStore */
#define CMBOXS_CLASS(so) CAMEL_MBOX_STORE_CLASS (GTK_OBJECT(so)->klass)
@@ -88,7 +88,7 @@ camel_mbox_store_get_type (void)
const gchar *
camel_mbox_store_get_toplevel_dir (CamelMboxStore *store)
{
- Gurl *url = CAMEL_SERVICE (store)->url;
+ CamelURL *url = CAMEL_SERVICE (store)->url;
g_assert(url != NULL);
return url->path;
diff --git a/camel/providers/pop3/camel-pop3-store.c b/camel/providers/pop3/camel-pop3-store.c
index 543a6ce532..f14ed1dc55 100644
--- a/camel/providers/pop3/camel-pop3-store.c
+++ b/camel/providers/pop3/camel-pop3-store.c
@@ -40,8 +40,8 @@
#include "camel-stream-fs.h"
#include "camel-session.h"
#include "camel-exception.h"
+#include "camel-url.h"
#include "md5-utils.h"
-#include "url-util.h"
/* Specified in RFC 1939 */
#define POP3_PORT 110
@@ -205,7 +205,7 @@ pop3_connect (CamelService *service, CamelException *ex)
{
struct hostent *h;
struct sockaddr_in sin;
- int port, fd, status, apoplen;
+ int fd, status, apoplen;
char *buf, *apoptime, *pass;
CamelPop3Store *store = CAMEL_POP3_STORE (service);
@@ -215,9 +215,6 @@ pop3_connect (CamelService *service, CamelException *ex)
h = camel_service_gethost (service, ex);
if (!h)
return FALSE;
- port = camel_service_getport (service, "pop3", POP3_PORT, "tcp", ex);
- if (port == -1)
- return FALSE;
pass = g_strdup (service->url->passwd);
if (!pass) {
@@ -233,7 +230,7 @@ pop3_connect (CamelService *service, CamelException *ex)
}
sin.sin_family = h->h_addrtype;
- sin.sin_port = port;
+ sin.sin_port = htons (service->url->port ? service->url->port : POP3_PORT);
memcpy (&sin.sin_addr, h->h_addr, sizeof (sin.sin_addr));
fd = socket (h->h_addrtype, SOCK_STREAM, 0);
diff --git a/camel/url-util.c b/camel/url-util.c
deleted file mode 100644
index 37a433888d..0000000000
--- a/camel/url-util.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* url-util.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
- */
-
-
-
-/*
- * Here we deal with URLs following the general scheme:
- * protocol://user;AUTH=mech:password@host:port/name
- * where name is a path-like string (ie dir1/dir2/....) See RFC 1738
- * for the complete description of Uniform Resource Locators. The
- * ";AUTH=mech" addition comes from RFC 2384, "POP URL Scheme".
- */
-
-/* XXX TODO:
- * recover the words between #'s or ?'s after the path
- * % escapes
- */
-
-#include <string.h>
-#include <config.h>
-#include "url-util.h"
-
-/**
- * g_url_new: create a Gurl object from a string
- *
- * @url_string: The string containing the URL to scan
- *
- * This routine takes a gchar and parses it as a
- * URL of the form:
- * protocol://user;AUTH=mech:password@host:port/path
- * There is no test on the values. For example,
- * "port" can be a string, not only a number!
- * The Gurl structure fields are filled with
- * the scan results. When a member of the
- * general URL can not be found, the corresponding
- * Gurl member is NULL.
- * Fields filled in the Gurl structure are allocated
- * and url_string is not modified.
- *
- * Return value: a Gurl structure containing the URL items.
- **/
-Gurl *g_url_new (const gchar* url_string)
-{
- Gurl *g_url;
- char *semi, *colon, *at, *slash;
-
- g_url = g_new (Gurl,1);
-
- /* Find protocol: initial substring until "://" */
- colon = strchr (url_string, ':');
- if (colon && !strncmp (colon, "://", 3)) {
- g_url->protocol = g_strndup (url_string, colon - url_string);
- url_string = colon + 3;
- } else
- g_url->protocol = NULL;
-
- /* If there is an @ sign, look for user, authmech, and
- * password before it.
- */
- at = strchr (url_string, '@');
- if (at) {
- colon = strchr (url_string, ':');
- if (colon && colon < at)
- g_url->passwd = g_strndup (colon + 1, at - colon - 1);
- else {
- g_url->passwd = NULL;
- colon = at;
- }
-
- semi = strchr(url_string, ';');
- if (semi && semi < colon && !strncasecmp (semi, ";auth=", 6))
- g_url->authmech = g_strndup (semi + 6, colon - semi - 6);
- else {
- g_url->authmech = NULL;
- semi = colon;
- }
-
- g_url->user = g_strndup (url_string, semi - url_string);
- url_string = at + 1;
- } else
- g_url->user = g_url->passwd = g_url->authmech = NULL;
-
- /* Find host (required) and port. */
- slash = strchr (url_string, '/');
- colon = strchr (url_string, ':');
- if (slash && colon > slash)
- colon = 0;
-
- if (colon) {
- g_url->host = g_strndup (url_string, colon - url_string);
- if (slash)
- g_url->port = g_strndup (colon + 1, slash - colon - 1);
- else
- g_url->port = g_strdup (colon + 1);
- } else if (slash) {
- g_url->host = g_strndup (url_string, slash - url_string);
- g_url->port = NULL;
- } else {
- g_url->host = g_strdup (url_string);
- g_url->port = NULL;
- }
-
- /* setup a fallback, if relative, then empty string, else
- it will be from root */
- if (slash == NULL) {
- slash = "/";
- }
- if (slash && *slash && g_url->protocol == NULL)
- slash++;
-
- g_url->path = g_strdup (slash);
-
- return g_url;
-}
-
-gchar *
-g_url_to_string (const Gurl *url, gboolean show_passwd)
-{
- return g_strdup_printf("%s%s%s%s%s%s%s%s%s%s%s%s",
- url->protocol ? url->protocol : "",
- url->protocol ? "://" : "",
- 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->port ? ":" : "",
- url->port ? url->port : "",
- url->path ? url->path : "");
-}
-
-void
-g_url_free (Gurl *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->port);
- g_free (url->path);
-
- g_free (url);
-}