1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
6 * Copyright (C) 2001 Ximian, Inc.
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 char *url)
45 const char *first_colon = NULL;
46 const char *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 char *url1, const char *url2)
90 char *shroud1 = e_url_shroud (url1);
91 char *shroud2 = e_url_shroud (url2);
95 if (shroud1 == NULL || shroud2 == NULL) {
96 rv = (shroud1 == shroud2);
98 len1 = strlen (shroud1);
99 len2 = strlen (shroud2);
101 rv = !strncmp (shroud1, shroud2, MIN (len1, len2));
110 #define HEXVAL(c) (isdigit (c) ? (c) - '0' : tolower (c) - 'a' + 10)
113 uri_decode (char *part)
117 s = d = (guchar *)part;
120 if (isxdigit (s[1]) && isxdigit (s[2])) {
121 *d++ = HEXVAL (s[1]) * 16 + HEXVAL (s[2]);
133 * @uri_string: The uri to represent as an #EUri.
135 * Creates an #EUri representation of the uri given in @uri_string.
137 * Returns: The newly-allocated #EUri structure.
140 e_uri_new (const char *uri_string)
143 const char *end, *hash, *colon, *semi, *at, *slash, *question;
149 uri = g_new0 (EUri, 1);
152 end = hash = strchr (uri_string, '#');
153 if (hash && hash[1]) {
154 uri->fragment = g_strdup (hash + 1);
155 uri_decode (uri->fragment);
158 end = uri_string + strlen (uri_string);
160 /* find protocol: initial [a-z+.-]* substring until ":" */
162 while (p < end && (isalnum ((unsigned char) *p) ||
163 *p == '.' || *p == '+' || *p == '-'))
166 if (p > uri_string && *p == ':') {
167 uri->protocol = g_ascii_strdown (uri_string, p - uri_string);
171 uri->protocol = g_strdup ("file");
176 /* check for authority */
177 if (strncmp (uri_string, "//", 2) == 0) {
180 slash = uri_string + strcspn (uri_string, "/#");
181 at = strchr (uri_string, '@');
182 if (at && at < slash) {
183 colon = strchr (uri_string, ':');
184 if (colon && colon < at) {
185 uri->passwd = g_strndup (colon + 1, at - colon - 1);
186 uri_decode (uri->passwd);
193 semi = strchr (uri_string, ';');
194 if (semi && semi < colon &&
195 !g_ascii_strncasecmp (semi, ";auth=", 6)) {
196 uri->authmech = g_strndup (semi + 6, colon - semi - 6);
197 uri_decode (uri->authmech);
200 uri->authmech = NULL;
204 uri->user = g_strndup (uri_string, semi - uri_string);
205 uri_decode (uri->user);
209 uri->user = uri->passwd = uri->authmech = NULL;
211 /* find host and port */
212 colon = strchr (uri_string, ':');
213 if (colon && colon < slash) {
214 uri->host = g_strndup (uri_string, colon - uri_string);
215 uri->port = strtoul (colon + 1, NULL, 10);
218 uri->host = g_strndup (uri_string, slash - uri_string);
219 uri_decode (uri->host);
227 question = memchr (uri_string, '?', end - uri_string);
230 uri->query = g_strndup (question + 1, end - (question + 1));
231 uri_decode (uri->query);
236 /* find parameters */
237 semi = memchr (uri_string, ';', end - uri_string);
240 const char *cur, *ptr, *eq;
243 for (cur = semi + 1; cur < end; cur = ptr + 1) {
244 ptr = memchr (cur, ';', end - cur);
247 eq = memchr (cur, '=', ptr - cur);
249 name = g_strndup (cur, eq - cur);
250 value = g_strndup (eq + 1, ptr - (eq + 1));
253 name = g_strndup (cur, ptr - cur);
254 value = g_strdup ("");
257 g_datalist_set_data_full (&uri->params, name,
265 if (end != uri_string) {
266 uri->path = g_strndup (uri_string, end - uri_string);
267 uri_decode (uri->path);
275 * @uri: A pointer to the #EUri to free.
277 * Frees the memory of an #EUri structure.
280 e_uri_free (EUri *uri)
283 g_free (uri->protocol);
285 g_free (uri->authmech);
286 g_free (uri->passwd);
289 g_datalist_clear (&uri->params);
291 g_free (uri->fragment);
299 * @uri: The #EUri to get the parameter from.
300 * @name: The name of the parameter to get.
302 * Retrieves the value of the parameter associated with @name in @uri.
304 * Returns: The value of the parameter.
307 e_uri_get_param (EUri *uri, const char *name)
309 return g_datalist_get_data (&uri->params, name);
313 copy_param_cb (GQuark key_id, gpointer data, gpointer user_data)
315 GData *params = (GData *) user_data;
317 g_datalist_id_set_data_full (¶ms, key_id, g_strdup (data), g_free);
322 * @uri: The #EUri to copy.
324 * Makes a copy of @uri.
326 * Returns: The newly-allocated copy of @uri.
329 e_uri_copy (EUri *uri)
333 g_return_val_if_fail (uri != NULL, NULL);
335 uri_copy = g_new0 (EUri, 1);
336 uri_copy->protocol = g_strdup (uri->protocol);
337 uri_copy->user = g_strdup (uri->user);
338 uri_copy->authmech = g_strdup (uri->authmech);
339 uri_copy->passwd = g_strdup (uri->passwd);
340 uri_copy->host = g_strdup (uri->host);
341 uri_copy->port = uri->port;
342 uri_copy->path = g_strdup (uri->path);
343 uri_copy->query = g_strdup (uri->query);
344 uri_copy->fragment = g_strdup (uri->fragment);
346 /* copy uri->params */
347 g_datalist_foreach (&uri->params,
348 (GDataForeachFunc) copy_param_cb,
356 * @uri: The #EUri to convert to a string.
357 * @show_password: Whether or not to show the password in the string.
359 * Creates a string representation of @uri. The password will only be
360 * included in the string if @show_password is set to %TRUE.
362 * Returns: The string representation of @uri.
365 e_uri_to_string (EUri *uri, gboolean show_password)
367 char *str_uri = NULL;
369 g_return_val_if_fail (uri != NULL, NULL);
372 str_uri = g_strdup_printf (
373 "%s://%s%s%s%s%s%s%s:%d%s%s%s",
375 uri->user ? uri->user : "",
376 uri->authmech ? ";auth=" : "",
377 uri->authmech ? uri->authmech : "",
378 uri->passwd && show_password ? ":" : "",
379 uri->passwd && show_password ? uri->passwd : "",
380 uri->user ? "@" : "",
381 uri->host ? uri->host : "",
383 uri->path ? uri->path : "",
384 uri->query ? "?" : "",
385 uri->query ? uri->query : "");
387 str_uri = g_strdup_printf(
388 "%s://%s%s%s%s%s%s%s%s%s%s",
390 uri->user ? uri->user : "",
391 uri->authmech ? ";auth=" : "",
392 uri->authmech ? uri->authmech : "",
393 uri->passwd && show_password ? ":" : "",
394 uri->passwd && show_password ? uri->passwd : "",
395 uri->user ? "@" : "",
396 uri->host ? uri->host : "",
397 uri->path ? uri->path : "",
398 uri->query ? "?" : "",
399 uri->query ? uri->query : "");