diff options
author | Dan Winship <danw@src.gnome.org> | 2000-02-17 01:05:57 +0800 |
---|---|---|
committer | Dan Winship <danw@src.gnome.org> | 2000-02-17 01:05:57 +0800 |
commit | d2239da3e7758ed99263b6623ab258561e10994d (patch) | |
tree | 91f6cc43929c00e4459fb4fe1610363244e7b664 /camel/url-util.c | |
parent | 8176cca8d02c90ed2b6ec3f48f95e7209e16389b (diff) | |
download | gsoc2013-evolution-d2239da3e7758ed99263b6623ab258561e10994d.tar gsoc2013-evolution-d2239da3e7758ed99263b6623ab258561e10994d.tar.gz gsoc2013-evolution-d2239da3e7758ed99263b6623ab258561e10994d.tar.bz2 gsoc2013-evolution-d2239da3e7758ed99263b6623ab258561e10994d.tar.lz gsoc2013-evolution-d2239da3e7758ed99263b6623ab258561e10994d.tar.xz gsoc2013-evolution-d2239da3e7758ed99263b6623ab258561e10994d.tar.zst gsoc2013-evolution-d2239da3e7758ed99263b6623ab258561e10994d.zip |
Simplify the code a lot and add support for RFC2384 POP URLs.
svn path=/trunk/; revision=1797
Diffstat (limited to 'camel/url-util.c')
-rw-r--r-- | camel/url-util.c | 432 |
1 files changed, 80 insertions, 352 deletions
diff --git a/camel/url-util.c b/camel/url-util.c index ba6bb1e813..91779873cb 100644 --- a/camel/url-util.c +++ b/camel/url-util.c @@ -3,10 +3,11 @@ /* - * 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 @@ -27,54 +28,33 @@ /* - Here we deal with URL following the general scheme: - protocol://user:password@host:port/name - where name is a path-like string (ie dir1/dir2/....) - See rfc1738 for the complete description of - Uniform Ressource Locators - - Bertrand. */ -/* - XXX TODO: recover the words between #'s or ?'s after the path */ + * 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 */ +#include <string.h> #include <config.h> #include "url-util.h" -/* general item finder */ -/* it begins the search at position @position in @url, - returns true when the item is found, amd set position after the item */ -typedef gboolean find_item_func(const gchar *url, gchar **item, guint *position, gboolean *error); - -/* used to find one item (protocol, then user .... */ -typedef struct { - char *item_name; /* item name : for debug only */ - gchar **item_value; /* where the item value will go */ - find_item_func *find_func; /* item finder */ -} FindStepStruct; - -static gboolean _find_protocol (const gchar *url, gchar **item, guint *position, gboolean *error); -static gboolean _find_user (const gchar *url, gchar **item, guint *position, gboolean *error); -static gboolean _find_passwd (const gchar *url, gchar **item, guint *position, gboolean *error); -static gboolean _find_host (const gchar *url, gchar **item, guint *position, gboolean *error); -static gboolean _find_port (const gchar *url, gchar **item, guint *position, gboolean *error); -static gboolean _find_path (const gchar *url, gchar **item, guint *position, gboolean *error); - - - /** - * g_url_new: create an Gurl object from a string + * 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 an + * This routine takes a gchar and parses it as a * URL of the form: - * protocol://user: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 ar filled with + * 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 + * Gurl member is NULL. * Fields filled in the Gurl structure are allocated * and url_string is not modified. * @@ -83,44 +63,71 @@ static gboolean _find_path (const gchar *url, gchar **item, guint *position, gbo Gurl *g_url_new (const gchar* url_string) { Gurl *g_url; - - gchar *protocol; - gchar *user; - gchar *passwd; - gchar *host; - gchar *port; - gchar *path; - - guint position = 0; - gboolean error; - gboolean found; - guint i; - + char *semi, *colon, *at, *slash; + g_url = g_new (Gurl,1); - -#define NB_STEP_URL 6 - { - FindStepStruct step[NB_STEP_URL] = { - { "protocol", &(g_url->protocol), _find_protocol}, - { "user", &(g_url->user), _find_user}, - { "password", &(g_url->passwd), _find_passwd}, - { "host", &(g_url->host), _find_host}, - { "port", &(g_url->port), _find_port}, - { "path", &(g_url->path), _find_path} - }; - - for (i = 0; i < NB_STEP_URL; i++) { - found = step[i].find_func (url_string, - step[i].item_value, - &position, - &error); + + /* 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; } - - return g_url; -} + if (slash && *(slash + 1)) + g_url->path = g_strdup (slash + 1); + else + g_url->path = NULL; + return g_url; +} void g_url_free (Gurl *url) @@ -129,290 +136,11 @@ g_url_free (Gurl *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); - -} - -/**** PARSING FUNCTIONS ****/ - -/* So, yes, I must admit there would have been more elegant - ways to do this, but it works, and quite well :) */ - - -static gboolean -_find_protocol (const gchar *url, gchar **item, guint *position, gboolean *error) -{ - - guint i; - gint len_url; - - g_assert (url); - g_assert (item); - g_assert (position); - - len_url = strlen (url); - - *item = NULL; - *error = FALSE; - i = *position; - - /* find a ':' */ - while ((i < len_url) && (url[i] != ':')) i++; - - if (i == len_url) return FALSE; - i++; - - /* check if it is followed by a "//" */ - if ((i < len_url) && (url[i++] == '/')) - if ((i < len_url) && (url[i++] == '/')) - { - *item = g_strndup (url, i-3); - *position = i; - return TRUE; - } - - return FALSE; -} - - - - -static gboolean -_find_user (const gchar *url, gchar **item, guint *position, gboolean *error) -{ - guint i; - guint at_pos; - gint len_url; - - g_assert (url); - g_assert (item); - g_assert (position); - - len_url = strlen (url); - *item = NULL; - i = *position; - - /* find a '@' */ - while ((i < len_url) && (url[i] != '@')) i++; - - if (i == len_url) return FALSE; - at_pos = i; - i = *position; - - /* find a ':' */ - while ((i < at_pos) && (url[i] != ':')) i++; - - /* now if i has not been incremented at all, there is no user */ - if (i == *position) { - (*position)++; - return FALSE; - } - - *item = g_strndup (url+ *position, i - *position); - if (i < at_pos) *position = i + 1; /* there was a ':', skip it */ - else *position = i; - - return TRUE; -} - -static gboolean -_find_passwd (const gchar *url, gchar **item, guint *position, gboolean *error) -{ - guint i; - gint len_url; - gchar *str_passwd; - - g_assert (url); - g_assert (item); - g_assert (position); - - len_url = strlen (url); - *item = NULL; - i = *position; - - /* find a '@' */ - while ((i < len_url) && (url[i] != '@')) i++; - - if (i == len_url) return FALSE; - /*i has not been incremented at all, there is no passwd */ - if (i == *position) { - *position = i + 1; - return FALSE; - } - - *item = g_strndup (url + *position, i - *position); - *position = i + 1; /* skip it the '@' */ - - return TRUE; -} - - - -static gboolean -_find_host (const gchar *url, gchar **item, guint *position, gboolean *error) -{ - guint i; - guint slash_pos; - gint len_url; - - g_assert (url); - g_assert (item); - g_assert (position); - - len_url = strlen (url); - *item = NULL; - i = *position; - - /* find a '/' */ - while ((i < len_url) && (url[i] != '/')) i++; - - slash_pos = i; - i = *position; - - /* find a ':' */ - while ( (i < slash_pos) && (url[i] != ':') ) i++; - - /* at this point if i has not been incremented at all, - there is no host */ - if (i == *position) { - /* if we have not met / or \0, we have : and must skip it */ - if (i < slash_pos) (*position)++; - return FALSE; - } - - *item = g_strndup (url + *position, i - *position); - if (i < slash_pos) *position = i + 1; /* there was a ':', skip it */ - else *position=i; - - return TRUE; -} - - -static gboolean -_find_port (const gchar *url, gchar **item, guint *position, gboolean *error) -{ - guint i; - guint slash_pos; - gint len_url; - - g_assert (url); - g_assert (item); - g_assert (position); - - len_url = strlen (url); - *item = NULL; - i=*position; - - /* find a '/' */ - while ((i < len_url) && (url[i] != '/')) i++; - - slash_pos = i; - i = *position; - - /* find a ':' */ - while ((i < slash_pos) && (url[i] != ':')) i++; - - /* at this point if i has not been incremented at all, */ - /* there is no port */ - if (i == *position) return FALSE; - - *item = g_strndup (url+ *position, i - *position); - *position = i; - return TRUE; } - - -static gboolean -_find_path (const gchar *url, gchar **item, guint *position, gboolean *error) -{ - guint i; - gint len_url; - - g_assert (url); - g_assert (item); - g_assert (position); - - len_url = strlen (url); - *item = NULL; - i = *position; - - - /* find a '#' */ - while ((i < len_url) && (url[i] != '#') && (url[i] != '?')) i++; - - /*i has not been incremented at all, there is no path */ - if (i == *position) return FALSE; - - *item = g_strndup (url + *position, i - *position); - *position=i; - - return TRUE; -} - - - - - -/**** TEST ROUTINE - NOT COMPILED BY DEFAULT ****/ - -/* to tests this file : - gcc -o test_url_util `glib-config --cflags` -I.. -DTEST_URL_UTIL url-util.c `glib-config --libs` - ./test_url_util URL -*/ -#ifdef TEST_URL_UTIL - - - -int -main (int argc, char **argv) -{ - - gchar *url; - gchar *protocol; - gchar *user; - gchar *passwd; - gchar *host; - gchar *port; - gchar *path; - guint position=0; - gboolean error; - gboolean found; - guint i; - guint i_pos; - -#define NB_STEP_TEST 6 - FindStepStruct test_step[NB_STEP_TEST] = { - { "protocol", &protocol, _find_protocol}, - { "user", &user, _find_user}, - { "password", &passwd, _find_passwd}, - { "host", &host, _find_host}, - { "port", &port, _find_port}, - { "path", &path, _find_path} - }; - url = argv[1]; - printf("URL to test : %s\n\n", url); - for (i=0; i<NB_STEP_TEST; i++) { - found = test_step[i].find_func (url, - test_step[i].item_value, - &position, - &error); - if (found) { - printf ("\t\t\t\t** %s found : %s\n", - test_step[i].item_name, - *(test_step[i].item_value)); - } else printf ("** %s not found in URL\n", test_step[i].item_name); - printf ("next item position:\n"); - printf ("%s\n", url); - for (i_pos = 0; i_pos < position; i_pos++) printf (" "); - printf ("^\n"); - - } - -} - -#endif /* TEST_URL_UTIL */ |