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 | |
parent | 080049ac37387efd71551bfdb661e15c0e1ce8ce (diff) | |
download | gsoc2013-evolution-2e4a5463075e387151afcdf61b74202a729944db.tar.gz 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
-rw-r--r-- | camel/ChangeLog | 9 | ||||
-rw-r--r-- | camel/Makefile.am | 4 | ||||
-rw-r--r-- | camel/camel-service.c | 76 | ||||
-rw-r--r-- | camel/camel-service.h | 14 | ||||
-rw-r--r-- | camel/camel-session.c | 18 | ||||
-rw-r--r-- | camel/camel-url.c | 188 | ||||
-rw-r--r-- | camel/camel-url.h (renamed from camel/url-util.h) | 43 | ||||
-rw-r--r-- | camel/camel.h | 2 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-store.c | 4 | ||||
-rw-r--r-- | camel/providers/pop3/camel-pop3-store.c | 9 | ||||
-rw-r--r-- | camel/url-util.c | 172 |
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); -} |