1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
6 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
8 * Developed by Jon Trowbridge <trow@ximian.com>
9 * Rodrigo Moya <rodrigo@ximian.com>
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of version 2 of the GNU Lesser General Public
15 * License as published by the Free Software Foundation.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
36 * @url: The url to shroud.
38 * Removes the moniker (i.e. mailto:) from a url.
40 * Returns: The newly-allocated shrouded url.
43 e_url_shroud (const gchar *url)
45 const gchar *first_colon = NULL;
46 const gchar *last_at = NULL;
53 /* Skip past the moniker */
54 for (p = url; *p && *p != ':'; ++p);
59 if (first_colon == NULL && *p == ':')
66 if (first_colon && last_at && first_colon < last_at) {
67 shrouded = g_malloc (first_colon - url + strlen (last_at) + 1);
68 memcpy (shrouded, url, first_colon - url);
69 strcpy (shrouded + (first_colon - url), last_at);
71 shrouded = g_strdup (url);
79 * @url1: The first url to compare.
80 * @url2: The second url to compare.
82 * Checks two urls for equality, after first removing any monikers on
85 * Returns: %TRUE if the urls are equal, %FALSE if they are not.
88 e_url_equal (const gchar *url1,
91 gchar *shroud1 = e_url_shroud (url1);
92 gchar *shroud2 = e_url_shroud (url2);
96 if (shroud1 == NULL || shroud2 == NULL) {
97 rv = (shroud1 == shroud2);
99 len1 = strlen (shroud1);
100 len2 = strlen (shroud2);
102 rv = !strncmp (shroud1, shroud2, MIN (len1, len2));
111 #define HEXVAL(c) (isdigit (c) ? (c) - '0' : tolower (c) - 'a' + 10)
114 uri_decode (gchar *part)
118 s = d = (guchar *) part;
121 if (isxdigit (s[1]) && isxdigit (s[2])) {
122 *d++ = HEXVAL (s[1]) * 16 + HEXVAL (s[2]);
134 * @uri_string: The uri to represent as an #EUri.
136 * Creates an #EUri representation of the uri given in @uri_string.
138 * Returns: The newly-allocated #EUri structure.
141 e_uri_new (const gchar *uri_string)
144 const gchar *end, *hash, *colon, *semi, *at, *slash, *question;
150 uri = g_new0 (EUri, 1);
153 end = hash = strchr (uri_string, '#');
154 if (hash && hash[1]) {
155 uri->fragment = g_strdup (hash + 1);
156 uri_decode (uri->fragment);
159 end = uri_string + strlen (uri_string);
161 /* find protocol: initial [a-z+.-]* substring until ":" */
163 while (p < end && (isalnum ((guchar) *p) ||
164 *p == '.' || *p == '+' || *p == '-'))
167 if (p > uri_string && *p == ':') {
168 uri->protocol = g_ascii_strdown (uri_string, p - uri_string);
172 uri->protocol = g_strdup ("file");
177 /* check for authority */
178 if (strncmp (uri_string, "//", 2) == 0) {
181 slash = uri_string + strcspn (uri_string, "/#");
182 at = strchr (uri_string, '@');
183 if (at && at < slash) {
185 /* this is for cases where username contains '@' at it, like:
186 * http://user@domain.com@server.addr.com/path
187 * We skip all at-s before the slash here. */
189 while (at2 = strchr (at + 1, '@'), at2 && at2 < slash) {
193 if (at && at < slash) {
194 colon = strchr (uri_string, ':');
195 if (colon && colon < at) {
196 uri->passwd = g_strndup (colon + 1, at - colon - 1);
197 uri_decode (uri->passwd);
204 semi = strchr (uri_string, ';');
205 if (semi && semi < colon &&
206 !g_ascii_strncasecmp (semi, ";auth=", 6)) {
207 uri->authmech = g_strndup (semi + 6, colon - semi - 6);
208 uri_decode (uri->authmech);
211 uri->authmech = NULL;
215 uri->user = g_strndup (uri_string, semi - uri_string);
216 uri_decode (uri->user);
220 uri->user = uri->passwd = uri->authmech = NULL;
222 /* find host and port */
223 colon = strchr (uri_string, ':');
224 if (colon && colon < slash) {
225 uri->host = g_strndup (uri_string, colon - uri_string);
226 uri->port = strtoul (colon + 1, NULL, 10);
229 uri->host = g_strndup (uri_string, slash - uri_string);
230 uri_decode (uri->host);
238 question = memchr (uri_string, '?', end - uri_string);
241 uri->query = g_strndup (question + 1, end - (question + 1));
242 uri_decode (uri->query);
247 /* find parameters */
248 semi = memchr (uri_string, ';', end - uri_string);
251 const gchar *cur, *ptr, *eq;
254 for (cur = semi + 1; cur < end; cur = ptr + 1) {
255 ptr = memchr (cur, ';', end - cur);
258 eq = memchr (cur, '=', ptr - cur);
260 name = g_strndup (cur, eq - cur);
261 value = g_strndup (eq + 1, ptr - (eq + 1));
264 name = g_strndup (cur, ptr - cur);
265 value = g_strdup ("");
268 g_datalist_set_data_full (
277 if (end != uri_string) {
278 uri->path = g_strndup (uri_string, end - uri_string);
279 uri_decode (uri->path);
287 * @uri: A pointer to the #EUri to free.
289 * Frees the memory of an #EUri structure.
292 e_uri_free (EUri *uri)
295 g_free (uri->protocol);
297 g_free (uri->authmech);
298 g_free (uri->passwd);
301 g_datalist_clear (&uri->params);
303 g_free (uri->fragment);
311 * @uri: The #EUri to get the parameter from.
312 * @name: The name of the parameter to get.
314 * Retrieves the value of the parameter associated with @name in @uri.
316 * Returns: The value of the parameter.
319 e_uri_get_param (EUri *uri,
322 return g_datalist_get_data (&uri->params, name);
326 copy_param_cb (GQuark key_id,
330 GData *params = (GData *) user_data;
332 g_datalist_id_set_data_full (¶ms, key_id, g_strdup (data), g_free);
337 * @uri: The #EUri to copy.
339 * Makes a copy of @uri.
341 * Returns: The newly-allocated copy of @uri.
344 e_uri_copy (EUri *uri)
348 g_return_val_if_fail (uri != NULL, NULL);
350 uri_copy = g_new0 (EUri, 1);
351 uri_copy->protocol = g_strdup (uri->protocol);
352 uri_copy->user = g_strdup (uri->user);
353 uri_copy->authmech = g_strdup (uri->authmech);
354 uri_copy->passwd = g_strdup (uri->passwd);
355 uri_copy->host = g_strdup (uri->host);
356 uri_copy->port = uri->port;
357 uri_copy->path = g_strdup (uri->path);
358 uri_copy->query = g_strdup (uri->query);
359 uri_copy->fragment = g_strdup (uri->fragment);
361 /* copy uri->params */
362 g_datalist_foreach (&uri->params,
363 (GDataForeachFunc) copy_param_cb,
371 * @uri: The #EUri to convert to a string.
372 * @show_password: Whether or not to show the password in the string.
374 * Creates a string representation of @uri. The password will only be
375 * included in the string if @show_password is set to %TRUE.
377 * Returns: The string representation of @uri.
380 e_uri_to_string (EUri *uri,
381 gboolean show_password)
383 gchar *str_uri = NULL;
385 g_return_val_if_fail (uri != NULL, NULL);
388 str_uri = g_strdup_printf (
389 "%s://%s%s%s%s%s%s%s:%d%s%s%s",
391 uri->user ? uri->user : "",
392 uri->authmech ? ";auth=" : "",
393 uri->authmech ? uri->authmech : "",
394 uri->passwd && show_password ? ":" : "",
395 uri->passwd && show_password ? uri->passwd : "",
396 uri->user ? "@" : "",
397 uri->host ? uri->host : "",
399 uri->path ? uri->path : "",
400 uri->query ? "?" : "",
401 uri->query ? uri->query : "");
403 str_uri = g_strdup_printf (
404 "%s://%s%s%s%s%s%s%s%s%s%s",
406 uri->user ? uri->user : "",
407 uri->authmech ? ";auth=" : "",
408 uri->authmech ? uri->authmech : "",
409 uri->passwd && show_password ? ":" : "",
410 uri->passwd && show_password ? uri->passwd : "",
411 uri->user ? "@" : "",
412 uri->host ? uri->host : "",
413 uri->path ? uri->path : "",
414 uri->query ? "?" : "",
415 uri->query ? uri->query : "");