summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2006-04-09 23:21:13 +0000
committerJohn Mark Bell <jmb@netsurf-browser.org>2006-04-09 23:21:13 +0000
commitc09eb457df1962f5b014214874b2beffd69141a4 (patch)
treea7c30e8b57b1d8bdeb87127c8f1ba16e91bf3971
parente5e1b982d55636b409b194cf0488ebafe9c6d519 (diff)
downloadnetsurf-c09eb457df1962f5b014214874b2beffd69141a4.tar.gz
netsurf-c09eb457df1962f5b014214874b2beffd69141a4.tar.bz2
Unify information databases
svn path=/trunk/netsurf/; revision=2519
-rw-r--r--content/authdb.c366
-rw-r--r--content/authdb.h18
-rw-r--r--content/certdb.c154
-rw-r--r--content/certdb.h18
-rw-r--r--content/fetch.c15
-rw-r--r--content/fetchcache.c1
-rw-r--r--content/url_store.c750
-rw-r--r--content/url_store.h61
-rw-r--r--content/urldb.c2231
-rw-r--r--content/urldb.h65
-rw-r--r--debug/netsurfd.c6
-rw-r--r--depend189
-rw-r--r--desktop/browser.c33
-rw-r--r--desktop/browser.h7
-rw-r--r--desktop/history_core.c6
-rw-r--r--desktop/options.c16
-rw-r--r--desktop/tree.c126
-rw-r--r--desktop/tree.h12
-rw-r--r--gtk/gtk_gui.c12
-rw-r--r--gtk/gtk_thumbnail.c6
-rw-r--r--gtk/gtk_treeview.c3
-rw-r--r--makefile12
-rw-r--r--posix.mk5
-rw-r--r--riscos/401login.c8
-rw-r--r--riscos/global_history.c166
-rw-r--r--riscos/global_history.h2
-rw-r--r--riscos/gui.c15
-rw-r--r--riscos/hotlist.c71
-rw-r--r--riscos/menus.c7
-rw-r--r--riscos/sslcert.c7
-rw-r--r--riscos/thumbnail.c4
-rw-r--r--riscos/treeview.c65
-rw-r--r--riscos/url_complete.c274
-rw-r--r--riscos/window.c6
-rw-r--r--utils/url.c59
-rw-r--r--utils/url.h1
36 files changed, 2959 insertions, 1838 deletions
diff --git a/content/authdb.c b/content/authdb.c
deleted file mode 100644
index f97adb1b0..000000000
--- a/content/authdb.c
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- * This file is part of NetSurf, http://netsurf.sourceforge.net/
- * Licensed under the GNU General Public License,
- * http://www.opensource.org/licenses/gpl-license
- * Copyright 2006 John M Bell <jmb202@ecs.soton.ac.uk>
- */
-
-/** \file
- * HTTP authentication database (implementation)
- *
- * Authentication details are stored hashed by canonical root URI
- * (absoluteURI with no abs_path part - see RFC 2617) for fast lookup.
- *
- * A protection space is specified by the root URI and a case sensitive
- * realm match. User-agents may preemptively send authentication details
- * for locations within a currently known protected space (i.e:
- * Given a known realm URI of scheme://authority/path/to/realm/
- * the URI scheme://authority/path/to/realm/foo/ can be assumed to
- * be within the protection space.)
- *
- * In order to deal with realms within realms, the realm details are stored
- * such that the most specific URI comes first (where "most specific" is
- * classed as the one with the longest abs_path segment).
- *
- * Realms spanning domains are stored multiple times (once per domain).
- *
- * Where a higher level resource is found to be within a known realm, the
- * existing match is replaced with the new one (i.e:
- * Given a known realm of scheme://authority/path/to/realm/ (uri1)
- * and the newly-acquired knowledge that scheme://authority/path/to/ (uri2)
- * lies within the same realm, the realm details for uri1 are replaced with
- * those for uri2. - in most cases, this is likely to be a simple
- * replacement of the realm URI)
- *
- * There is currently no mechanism for retaining authentication details over
- * sessions.
- */
-#include <assert.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-#include "netsurf/content/authdb.h"
-#define NDEBUG
-#include "netsurf/utils/log.h"
-#include "netsurf/utils/url.h"
-
-#define HASH_SIZE 77
-
-struct realm_details {
- char *realm; /**< Realm identifier */
- char *url; /**< Base URL of realm */
- char *auth; /**< Authentication details */
- struct realm_details *next;
- struct realm_details *prev;
-};
-
-struct auth_entry {
- char *root_url; /**< Canonical root URL of realms */
- struct realm_details *realms; /**< List of realms on this host */
- struct auth_entry *next;
-};
-
-static struct auth_entry *auth_table[HASH_SIZE];
-
-static unsigned int authdb_hash(const char *s);
-static struct realm_details *authdb_get_rd(const char *canon,
- const char *url, const char *realm);
-static void authdb_dump(void);
-
-/**
- * Insert an entry into the database, potentially replacing any
- * existing entry.
- *
- * \param url Absolute URL to resource
- * \param realm Authentication realm containing resource
- * \param auth Authentication details in form "username:password"
- * \return true on success, false on error.
- */
-bool authdb_insert(const char *url, const char *realm, const char *auth)
-{
- char *canon, *stripped;
- unsigned int hash;
- struct realm_details *rd;
- struct auth_entry *entry;
- url_func_result ret;
-
- assert(url && realm && auth);
-
- LOG(("Adding '%s' - '%s'", url, realm));
-
- ret = url_canonical_root(url, &canon);
- if (ret != URL_FUNC_OK)
- return false;
-
- LOG(("'%s'", canon));
-
- ret = url_strip_lqf(url, &stripped);
- if (ret != URL_FUNC_OK) {
- free(canon);
- return false;
- }
-
- hash = authdb_hash(canon);
-
- /* Look for existing entry */
- for (entry = auth_table[hash]; entry; entry = entry->next)
- if (strcmp(entry->root_url, canon) == 0)
- break;
-
- rd = authdb_get_rd(canon, stripped, realm);
- if (rd) {
- /* We have a match */
- if (strlen(stripped) < strlen(rd->url)) {
- /* more generic, so update URL and move to
- * appropriate location in list (s.t. the invariant
- * that most specific URLs come first is maintained)
- */
- struct realm_details *r, *s;
- char *temp = strdup(auth);
-
- if (!temp) {
- free(temp);
- free(stripped);
- free(canon);
- return false;
- }
-
- free(rd->url);
- rd->url = stripped;
-
- free(rd->auth);
- rd->auth = temp;
-
- for (r = rd->next; r; r = s) {
- s = r->next;
- if (strlen(r->url) > strlen(rd->url)) {
- rd->next->prev = rd->prev;
- if (rd->prev)
- rd->prev->next = rd->next;
- else
- entry->realms = r;
-
- rd->prev = r;
- rd->next = r->next;
- if (r->next)
- r->next->prev = rd;
- r->next = rd;
- }
- }
- }
- else if (strlen(stripped) == strlen(rd->url)) {
- /* exact match, so replace auth details */
- char *temp = strdup(auth);
- if (!temp) {
- free(stripped);
- free(canon);
- return false;
- }
-
- free(rd->auth);
- rd->auth = temp;
-
- free(stripped);
- }
- /* otherwise, nothing to do */
-
- free(canon);
- return true;
- }
-
- /* no existing entry => create one */
- rd = malloc(sizeof(struct realm_details));
- if (!rd) {
- free(stripped);
- free(canon);
- return false;
- }
-
- rd->realm = strdup(realm);
- rd->auth = strdup(auth);
- rd->url = stripped;
- rd->prev = 0;
-
- if (!rd->realm || !rd->auth || ret != URL_FUNC_OK) {
- free(rd->url);
- free(rd->auth);
- free(rd->realm);
- free(rd);
- free(canon);
- return false;
- }
-
- if (entry) {
- /* found => add to it */
- rd->next = entry->realms;
- if (entry->realms)
- entry->realms->prev = rd;
- entry->realms = rd;
-
- free(canon);
- return true;
- }
-
- /* not found => create new */
- entry = malloc(sizeof(struct auth_entry));
- if (!entry) {
- free(rd->url);
- free(rd->auth);
- free(rd->realm);
- free(rd);
- free(canon);
- return false;
- }
-
- rd->next = 0;
- entry->root_url = canon;
- entry->realms = rd;
- entry->next = auth_table[hash];
- auth_table[hash] = entry;
-
- return true;
-}
-
-/**
- * Find realm details entry
- *
- * \param canon Canonical root URL
- * \param url Stripped URL to resource
- * \param realm Realm containing resource
- * \return Realm details or NULL if not found
- */
-struct realm_details *authdb_get_rd(const char *canon, const char *url,
- const char *realm)
-{
- struct auth_entry *entry;
- struct realm_details *ret;
-
- assert(canon && url);
-
- for (entry = auth_table[authdb_hash(canon)]; entry;
- entry = entry->next)
- if (strcmp(entry->root_url, canon) == 0)
- break;
-
- if (!entry)
- return NULL;
-
- for (ret = entry->realms; ret; ret = ret->next) {
- if (strcmp(ret->realm, realm))
- /* skip realms that don't match */
- continue;
- if (strlen(url) >= strlen(ret->url) &&
- !strncmp(url, ret->url, strlen(ret->url)))
- /* If the requested URL is of equal or greater
- * specificity than the stored one, but is within
- * the same realm, then use the more generic details
- */
- return ret;
- else if (strncmp(url, ret->url, strlen(url)) == 0) {
- /* We have a more general URL in the same realm */
- return ret;
- }
- }
-
- return NULL;
-}
-
-/**
- * Retrieve authentication details for an URL from the database
- *
- * \param url Absolute URL to consider
- * \return authentication details, or NULL if none found.
- */
-const char *authdb_get(const char *url)
-{
- char *canon, *stripped;
- struct auth_entry *entry;
- struct realm_details *rd;
- url_func_result ret;
-
- assert(url);
-
- LOG(("Searching for '%s'", url));
-
- authdb_dump();
-
- ret = url_canonical_root(url, &canon);
- if (ret != URL_FUNC_OK)
- return NULL;
-
- ret = url_strip_lqf(url, &stripped);
- if (ret != URL_FUNC_OK) {
- free(canon);
- return NULL;
- }
-
- /* Find auth entry */
- for (entry = auth_table[authdb_hash(canon)]; entry;
- entry = entry->next)
- if (strcmp(entry->root_url, canon) == 0)
- break;
-
- if (!entry) {
- free(stripped);
- free(canon);
- return NULL;
- }
-
- LOG(("Found entry"));
-
- /* Find realm details */
- for (rd = entry->realms; rd; rd = rd->next)
- if (strlen(stripped) >= strlen(rd->url) &&
- !strncmp(stripped, rd->url, strlen(rd->url)))
- break;
-
- if (!rd) {
- free(stripped);
- free(canon);
- return NULL;
- }
-
- LOG(("Found realm"));
-
- free(stripped);
- free(canon);
- return rd->auth;
-}
-
-/**
- * Hash function for keys.
- */
-unsigned int authdb_hash(const char *s)
-{
- unsigned int i, z = 0, m;
- if (!s)
- return 0;
-
- m = strlen(s);
-
- for (i = 0; i != m && s[i]; i++)
- z += s[i] & 0x1f; /* lower 5 bits, case insensitive */
- return z % HASH_SIZE;
-}
-
-/**
- * Dump contents of auth db to stderr
- */
-void authdb_dump(void)
-{
-#ifndef NDEBUG
- int i;
- struct auth_entry *e;
- struct realm_details *r;
-
- for (i = 0; i != HASH_SIZE; i++) {
- LOG(("%d:", i));
- for (e = auth_table[i]; e; e = e->next) {
- LOG(("\t%s", e->root_url));
- for (r = e->realms; r; r = r->next) {
- LOG(("\t\t%s - %s", r->url, r->realm));
- }
- }
- }
-#endif
-}
diff --git a/content/authdb.h b/content/authdb.h
deleted file mode 100644
index ece7b763d..000000000
--- a/content/authdb.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * This file is part of NetSurf, http://netsurf.sourceforge.net/
- * Licensed under the GNU General Public License,
- * http://www.opensource.org/licenses/gpl-license
- * Copyright 2006 John M Bell <jmb202@ecs.soton.ac.uk>
- */
-
-/** \file
- * HTTP authentication database (interface)
- */
-
-#ifndef _NETSURF_CONTENT_AUTHDB_H_
-#define _NETSURF_CONTENT_AUTHDB_H_
-
-bool authdb_insert(const char *url, const char *realm, const char *auth);
-const char *authdb_get(const char *url);
-
-#endif
diff --git a/content/certdb.c b/content/certdb.c
deleted file mode 100644
index 78c6ec04f..000000000
--- a/content/certdb.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * This file is part of NetSurf, http://netsurf.sourceforge.net/
- * Licensed under the GNU General Public License,
- * http://www.opensource.org/licenses/gpl-license
- * Copyright 2006 John M Bell <jmb202@ecs.soton.ac.uk>
- */
-
-/** \file
- * HTTPS certificate verification database (implementation)
- *
- * URLs of servers with invalid SSL certificates are stored hashed by
- * canonical root URI (absoluteURI with no abs_path part - see RFC 2617)
- * for fast lookup.
- */
-#include <assert.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-#include "netsurf/utils/config.h"
-#include "netsurf/content/certdb.h"
-#define NDEBUG
-#include "netsurf/utils/log.h"
-#include "netsurf/utils/url.h"
-
-#define HASH_SIZE 77
-
-#ifdef WITH_SSL
-
-struct cert_entry {
- char *root_url; /**< Canonical root URL */
- struct cert_entry *next;
-};
-
-static struct cert_entry *cert_table[HASH_SIZE];
-
-static unsigned int certdb_hash(const char *s);
-static void certdb_dump(void);
-
-/**
- * Insert an entry into the database
- *
- * \param url Absolute URL to resource
- * \return true on success, false on error.
- */
-bool certdb_insert(const char *url)
-{
- char *canon;
- unsigned int hash;
- struct cert_entry *entry;
- url_func_result ret;
-
- assert(url);
-
- LOG(("Adding '%s'", url));
-
- ret = url_canonical_root(url, &canon);
- if (ret != URL_FUNC_OK)
- return false;
-
- LOG(("'%s'", canon));
-
- hash = certdb_hash(canon);
-
- /* Look for existing entry */
- for (entry = cert_table[hash]; entry; entry = entry->next) {
- if (strcmp(entry->root_url, canon) == 0) {
- free(canon);
- return true;
- }
- }
-
- /* not found => create new */
- entry = malloc(sizeof(struct cert_entry));
- if (!entry) {
- free(canon);
- return false;
- }
-
- entry->root_url = canon;
- entry->next = cert_table[hash];
- cert_table[hash] = entry;
-
- return true;
-}
-
-/**
- * Retrieve certificate details for an URL from the database
- *
- * \param url Absolute URL to consider
- * \return certificate details, or NULL if none found.
- */
-const char *certdb_get(const char *url)
-{
- char *canon;
- struct cert_entry *entry;
- url_func_result ret;
-
- assert(url);
-
- LOG(("Searching for '%s'", url));
-
- certdb_dump();
-
- ret = url_canonical_root(url, &canon);
- if (ret != URL_FUNC_OK)
- return NULL;
-
- /* Find cert entry */
- for (entry = cert_table[certdb_hash(canon)]; entry;
- entry = entry->next) {
- if (strcmp(entry->root_url, canon) == 0) {
- free(canon);
- return entry->root_url;
- }
- }
-
- return NULL;
-}
-
-/**
- * Hash function for keys.
- */
-unsigned int certdb_hash(const char *s)
-{
- unsigned int i, z = 0, m;
- if (!s)
- return 0;
-
- m = strlen(s);
-
- for (i = 0; i != m && s[i]; i++)
- z += s[i] & 0x1f; /* lower 5 bits, case insensitive */
- return z % HASH_SIZE;
-}
-
-/**
- * Dump contents of auth db to stderr
- */
-void certdb_dump(void)
-{
-#ifndef NDEBUG
- int i;
- struct cert_entry *e;
-
- for (i = 0; i != HASH_SIZE; i++) {
- LOG(("%d:", i));
- for (e = cert_table[i]; e; e = e->next) {
- LOG(("\t%s", e->root_url));
- }
- }
-#endif
-}
-
-#endif
diff --git a/content/certdb.h b/content/certdb.h
deleted file mode 100644
index 28aa88664..000000000
--- a/content/certdb.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * This file is part of NetSurf, http://netsurf.sourceforge.net/
- * Licensed under the GNU General Public License,
- * http://www.opensource.org/licenses/gpl-license
- * Copyright 2006 John M Bell <jmb202@ecs.soton.ac.uk>
- */
-
-/** \file
- * HTTPS certificate verification database (interface)
- */
-
-#ifndef _NETSURF_CONTENT_CERTDB_H_
-#define _NETSURF_CONTENT_CERTDB_H_
-
-bool certdb_insert(const char *url);
-const char *certdb_get(const char *url);
-
-#endif
diff --git a/content/fetch.c b/content/fetch.c
index 4ba322067..bfbf715a0 100644
--- a/content/fetch.c
+++ b/content/fetch.c
@@ -31,13 +31,8 @@
#ifdef WITH_SSL
#include "openssl/ssl.h"
#endif
-#ifdef WITH_AUTH
-#include "netsurf/content/authdb.h"
-#endif
-#ifdef WITH_SSL
-#include "netsurf/content/certdb.h"
-#endif
#include "netsurf/content/fetch.h"
+#include "netsurf/content/urldb.h"
#include "netsurf/desktop/options.h"
#include "netsurf/render/form.h"
#define NDEBUG
@@ -158,7 +153,7 @@ static int fetch_cert_verify_callback(X509_STORE_CTX *x509_ctx, void *parm);
ring = 0; \
} \
element->r_next = element->r_prev = 0
-
+
/** Find the element (by hostname) in the given ring, leave it in the
* provided element variable
*/
@@ -483,7 +478,7 @@ static bool ns_internal_initiate_fetch(struct fetch *fetch, CURL *handle)
fetch->curl_handle = 0;
return false;
}
-
+
/* add to the global curl multi handle */
codem = curl_multi_add_handle(fetch_curl_multi, fetch->curl_handle);
assert(codem == CURLM_OK || codem == CURLM_CALL_MULTI_PERFORM);
@@ -649,7 +644,7 @@ CURLcode fetch_set_options(struct fetch *f)
SETOPT(CURLOPT_COOKIEJAR, 0);
}
#ifdef WITH_AUTH
- if ((auth = authdb_get(f->url)) != NULL) {
+ if ((auth = urldb_get_auth_details(f->url)) != NULL) {
SETOPT(CURLOPT_HTTPAUTH, CURLAUTH_ANY);
SETOPT(CURLOPT_USERPWD, auth);
} else {
@@ -677,7 +672,7 @@ CURLcode fetch_set_options(struct fetch *f)
}
#ifdef WITH_SSL
- if (certdb_get(f->url) != NULL) {
+ if (urldb_get_cert_permissions(f->url)) {
/* Disable certificate verification */
SETOPT(CURLOPT_SSL_VERIFYPEER, 0L);
SETOPT(CURLOPT_SSL_VERIFYHOST, 0L);
diff --git a/content/fetchcache.c b/content/fetchcache.c
index 47f24e89c..bc8907f14 100644
--- a/content/fetchcache.c
+++ b/content/fetchcache.c
@@ -23,7 +23,6 @@
#include "netsurf/content/content.h"
#include "netsurf/content/fetchcache.h"
#include "netsurf/content/fetch.h"
-#include "netsurf/content/url_store.h"
#include "netsurf/utils/log.h"
#include "netsurf/utils/messages.h"
#include "netsurf/utils/talloc.h"
diff --git a/content/url_store.c b/content/url_store.c
deleted file mode 100644
index fde956e46..000000000
--- a/content/url_store.c
+++ /dev/null
@@ -1,750 +0,0 @@
-/*
- * This file is part of NetSurf, http://netsurf.sourceforge.net/
- * Licensed under the GNU General Public License,
- * http://www.opensource.org/licenses/gpl-license
- * Copyright 2005 Richard Wilson <info@tinct.net>
- */
-
-/** \file
- * Central repository for URL data (implementation).
- */
-
-#include <assert.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include "netsurf/content/url_store.h"
-#include "netsurf/image/bitmap.h"
-#include "netsurf/desktop/options.h"
-#ifdef riscos
-#include "netsurf/riscos/bitmap.h"
-#endif
-#include "netsurf/utils/log.h"
-#include "netsurf/utils/url.h"
-#include "netsurf/utils/utils.h"
-
-
-#define ITERATIONS_BEFORE_TEST 32
-#define MAXIMUM_URL_LENGTH 1024
-
-struct hostname_data *url_store_hostnames = NULL;
-
-static struct hostname_data *url_store_find_hostname(const char *url);
-static struct hostname_data *url_store_match_hostname(
- struct hostname_data *previous);
-
-/* used for faster matching */
-static size_t current_match_url_length;
-static char *current_match_scheme;
-static int current_match_scheme_length;
-static char *current_match_hostname;
-static int current_match_hostname_length;
-static bool current_match_www_test;
-
-/* used for faster searching */
-static struct hostname_data *last_hostname_found = NULL;
-
-/**
- * Returns the hostname data for the specified URL. If no hostname
- * data is currently available then it is created.
- *
- * \param url the url to find hostname data for
- * \return the current hostname data, or NULL if memory exhausted
- */
-struct hostname_data *url_store_find_hostname(const char *url)
-{
- struct hostname_data *first = url_store_hostnames;
- struct hostname_data *search;
- struct hostname_data *result;
- url_func_result res;
- char *hostname = NULL;
- int hostname_length;
- int compare;
- int fast_exit_counter = ITERATIONS_BEFORE_TEST;
- const char *host_test;
-
- assert(url);
-
- /* as the URL is normalised, we optimise the hostname finding for http:// */
- if (!strncmp("http://", url, 7)) {
- /* check for duplicate hostname calls */
- if ((last_hostname_found) &&
- (!strncmp(last_hostname_found->hostname, url + 7,
- last_hostname_found->hostname_length))) {
- /* ensure it isn't comparing 'foo.com' to 'foo.com.au' etc */
- if (url[last_hostname_found->hostname_length + 7] != '.')
- return last_hostname_found;
- }
-
- /* check for a hostname match */
- for (host_test = url + 7;
- ((*host_test > 32) && (*host_test != '/'));
- *host_test++);
- hostname_length = host_test - url - 7;
- host_test = url + 7;
- if ((last_hostname_found) &&
- (strncmp(host_test,
- last_hostname_found->hostname,
- hostname_length) > 0))
- first = last_hostname_found;
- for (search = first; search; search = search->next) {
- if (search->hostname_length == hostname_length) {
- compare = strncmp(host_test, search->hostname,
- hostname_length);
- if (compare == 0) {
- last_hostname_found = search;
- return search;
- } else if (compare < 0)
- break;
- }
- }
-
- /* allocate a new hostname */
- hostname = malloc(hostname_length + 1);
- if (!hostname)
- return NULL;
- memcpy(hostname, host_test, hostname_length);
- hostname[hostname_length] = '\0';
- } else {
- /* no quick match found, fallback */
- res = url_host(url, &hostname);
- switch (res) {
- case URL_FUNC_OK:
- break;
- case URL_FUNC_NOMEM:
- return NULL;
- case URL_FUNC_FAILED:
- hostname = strdup("file:/"); /* for 'file:/' */
- if (!hostname)
- return NULL;
- break;
- default:
- assert(0);
- }
- hostname_length = strlen(hostname);
- }
-
- /* try to find a matching hostname fairly quickly */
- if ((last_hostname_found) &&
- (strcmp(hostname, last_hostname_found->hostname) > 0))
- first = last_hostname_found;
- for (search = first; search; search = search->next) {
- if ((fast_exit_counter <= 0) ||
- (search->hostname_length == hostname_length)) {
- compare = strcmp(hostname, search->hostname);
- if (compare == 0) {
- free(hostname);
- last_hostname_found = search;
- return search;
- } else if (compare < 0)
- break;
- fast_exit_counter = ITERATIONS_BEFORE_TEST;
- } else {
- fast_exit_counter--;
- }
- }
-
- /* no hostname is available: create a new one */
- result = malloc(sizeof *result);
- if (!result) {
- free(hostname);
- return NULL;
- }
- result->hostname = hostname;
- result->hostname_length = hostname_length;
- result->url = 0;
- result->previous = 0;
- result->next = 0;
- last_hostname_found = result;
-
- /* simple case: no current hostnames */
- if (!url_store_hostnames) {
- url_store_hostnames = result;
- return result;
- }
-
- /* worst case scenario: the place we need to link is within the last
- * section of the hostname list so we have no reference to work back
- * from. rather than slowing with the very common case of searching,
- * we take a speed hit for this case and simply move to the very end
- * of the hostname list ready to work backwards. */
- if (!search)
- for (search = url_store_hostnames; search->next;
- search = search->next)
- ;
-
- /* we can now simply scan backwards as we know roughly where we need
- * to link to (we either had an early exit from the searching so we
- * know we're in the block following where we need to link, or we're
- * at the very end of the list as we were in the last block.) */
- while ((search) && (strcmp(hostname, search->hostname) < 0))
- search = search->previous;
-
- /* simple case: our new hostname is the first in the list */
- if (!search) {
- result->next = url_store_hostnames;
- url_store_hostnames->previous = result;
- url_store_hostnames = result;
- return result;
- }
-
- /* general case: link in after the found hostname */
- result->previous = search;
- result->next = search->next;
- if (search->next)
- search->next->previous = result;
- search->next = result;
- return result;
-}
-
-
-/**
- * Returns the url data for the specified URL. If no url
- * data is currently available then it is created.
- *
- * \param url a normalized url to find hostname data for
- * \return the current hostname data, or NULL if memory exhausted
- */
-struct url_content *url_store_find(const char *url) {
- struct hostname_data *hostname_data;
- struct url_data *search;
- struct url_data *result;
- size_t url_length;
- int compare;
- int fast_exit_counter = ITERATIONS_BEFORE_TEST;
-
- assert(url);
-
- /* find the corresponding hostname data */
- hostname_data = url_store_find_hostname(url);
- if (!hostname_data)
- return NULL;
-
- /* move to the start of the leafname */
- url_length = strlen(url);
-
- /* try to find a matching url fairly quickly */
- for (search = hostname_data->url; search; search = search->next) {
- if ((fast_exit_counter <= 0) ||
- (search->data.url_length == url_length)) {
- compare = strcmp(url, search->data.url);
- if (compare == 0)
- return &search->data;
- else if (compare < 0)
- break;
- fast_exit_counter = ITERATIONS_BEFORE_TEST;
- } else {
- fast_exit_counter--;
- }
- }
-
- /* no URL is available: create a new one */
- result = calloc(1, sizeof(struct url_data));
- if (!result)
- return NULL;
- result->data.url = malloc(url_length + 1);
- if (!result->data.url) {
- free(result);
- return NULL;
- }
- memcpy(result->data.url, url, url_length + 1);
- result->data.url_length = url_length;
- result->parent = hostname_data;
-
- /* simple case: no current URLs */
- if (!hostname_data->url) {
- hostname_data->url = result;
- return &result->data;
- }
-
- /* worst case scenario: the place we need to link is within the last
- * section of the URL list so we have no reference to work back
- * from. rather than slowing with the very common case of searching,
- * we take a speed hit for this case and simply move to the very end
- * of the URL list ready to work backwards. */
- if (!search)
- for (search = hostname_data->url; search->next;
- search = search->next)
- ;
-
- /* we can now simply scan backwards as we know roughly where we need
- * to link to (we either had an early exit from the searching so we
- * know we're in the block following where we need to link, or we're
- * at the very end of the list as we were in the last block.) */
- while ((search) && (strcmp(url, search->data.url) < 0))
- search = search->previous;
-
- /* simple case: our new hostname is the first in the list */
- if (!search) {
- result->next = hostname_data->url;
- hostname_data->url->previous = result;
- hostname_data->url = result;
- return &result->data;
- }
-
- /* general case: link in after the found hostname */
- result->previous = search;
- result->next = search->next;
- if (search->next)
- search->next->previous = result;
- search->next = result;
- return &result->data;
-}
-
-
-/**
- * Returns the next hostname that matches a part of the specified URL.
- *
- * The following variables must be initialised prior to calling:
- *
- * - current_match_scheme
- * - current_match_hostname
- * - current_match_hostname_length;
- *
- * \param url a normalized url to find the next match for
- * \param current the current hostname to search forward from, or NULL
- * \return the next matching hostname, or NULL
- */
-struct hostname_data *url_store_match_hostname(
- struct hostname_data *current) {
- int compare;
-
- assert(current_match_hostname);
-
- /* advance to the next hostname */
- if (!current)
- current = url_store_hostnames;
- else
- current = current->next;
-
- /* skip past hostname data without URLs */
- for (; current && (!current->url); current = current->next);
-
- while (current) {
- if (current->hostname_length >= current_match_hostname_length) {
- compare = strncmp(current_match_hostname, current->hostname,
- current_match_hostname_length);
- if (compare == 0)
- return current;
- else if ((compare < 0) && !current_match_www_test)
- break;
- }
- /* special case: if hostname is not www then try it */
- if (current_match_www_test && ((current->hostname_length - 4) >=
- current_match_hostname_length) &&
- (!strncmp(current->hostname, "www.", 4)) &&
- (!strncmp(current_match_hostname,
- current->hostname + 4,
- current_match_hostname_length)))
- return current;
-
- /* move to next hostname with URLs */
- current = current->next;
- for (; current && (!current->url); current = current->next);
- }
- return NULL;
-}
-
-
-
-/**
- * Returns the complete URL for the next matched stored URL.
- *
- * \param url a normalized url to find the next match for
- * \param reference internal reference (NULL for first call)
- * \return the next URL that matches
- */
-struct url_content *url_store_match(const char *url, struct url_data **reference) {
- struct hostname_data *hostname;
- struct url_data *search = NULL;
- url_func_result res;
-
- assert(url);
-
- if (!url_store_hostnames)
- return NULL;
-
- /* find the scheme and first URL, not necessarily matching */
- if (!*reference) {
- /* the hostname match is constant throughout */
- if (current_match_hostname)
- free(current_match_hostname);
- current_match_hostname = NULL;
- res = url_host(url, &current_match_hostname);
- switch (res) {
- case URL_FUNC_OK:
- break;
- case URL_FUNC_NOMEM:
- return NULL;
- case URL_FUNC_FAILED:
- /* for 'file:/' */
- current_match_hostname = strdup("file:/");
- if (!current_match_hostname)
- return NULL;
- break;
- default:
- assert(0);
- }
- current_match_hostname_length = strlen(current_match_hostname);
- /* the scheme is constant throughout */
- if (current_match_scheme)
- free(current_match_scheme);
- current_match_scheme = NULL;
- res = url_scheme(url, &current_match_scheme);
- if (res != URL_FUNC_OK)
- return NULL;
- current_match_scheme_length = strlen(current_match_scheme);
- /* the url is constant throughout */
- current_match_url_length = strlen(url);
- current_match_www_test = (!strcmp(current_match_scheme, "http") &&
- strncmp(url + 4 + 3, "www.", 4)); /* 'http' + '://' */
- /* get our initial reference */
- hostname = url_store_match_hostname(NULL);
- if (!hostname)
- return NULL;
- } else {
- search = *reference;
- hostname = search->parent;
- }
-
- /* work through all our strings, ignoring the scheme and 'www.' */
- while (hostname) {
-
- /* get the next URL to test */
- if (!search)
- search = hostname->url;
- else
- search = search->next;
-
- /* loop past end of list, or search */
- if (!search) {
- hostname = url_store_match_hostname(hostname);
- if (!hostname)
- return NULL;
- } else if (search->data.visits > 0) {
- /* straight match */
- if ((search->data.url_length >= current_match_url_length) &&
- (!strncmp(search->data.url, url,
- current_match_url_length))) {
- *reference = search;
- return &search->data;
- }
- /* try with 'www.' inserted after the scheme */
- if (current_match_www_test &&
- ((search->data.url_length - 4) >=
- current_match_url_length) &&
- (!strncmp(search->data.url,
- current_match_scheme,
- current_match_scheme_length)) &&
- (!strncmp(search->data.url +
- current_match_scheme_length + 3,
- "www.", 4)) &&
- (!strncmp(search->data.url +
- current_match_scheme_length + 7,
- url +
- current_match_scheme_length + 3,
- current_match_url_length -
- current_match_scheme_length - 3))) {
- *reference = search;
- return &search->data;
- }
- }
- }
- return NULL;
-}
-
-
-/**
- * Converts a text string into one suitable for URL matching.
- *
- * \param text the text to search with
- * \return URL matching string allocated on heap, or NULL on error
- */
-char *url_store_match_string(const char *text) {
- url_func_result res;
- char *url;
-
- assert(text);
-
- res = url_normalize(text, &url);
- if (res != URL_FUNC_OK)
- return NULL;
-
- /* drop the '/' from the end if it was added when normalizing */
- if ((url[strlen(url) - 1] == '/') && (text[strlen(text) - 1] != '/'))
- url[strlen(url) - 1] = '\0';
- return url;
-}
-
-
-/**
- * Loads the current contents of the URL store from disk
- *
- * \param file the file to load options from
- */
-void url_store_load(const char *file) {
- char s[MAXIMUM_URL_LENGTH];
- struct hostname_data *hostname;
- struct url_data *result;
- int urls;
- int i;
- int version;
- int length;
- FILE *fp;
-
- LOG(("Loading URL file"));
-
- fp = fopen(file, "r");
- if (!fp) {
- LOG(("Failed to open file '%s' for reading", file));
- return;
- }
-
- if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
- return;
- version = atoi(s);
- if (version < 102) {
- LOG(("Unsupported URL file version."));
- return;
- }
- if (version > 105) {
- LOG(("Unknown URL file version."));
- return;
- }
-
- last_hostname_found = NULL;
- while (fgets(s, MAXIMUM_URL_LENGTH, fp)) {
- /* get the hostname */
- length = strlen(s) - 1;
- s[length] = '\0';
-
- /* skip data that has ended up with a host of '' */
- if (length == 0) {
- if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
- break;
- urls = atoi(s);
- for (i = 0; i < (6 * urls); i++)
- if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
- break;
- continue;
- }
-
- /* add the host at the tail */
- if (version == 105) {
- hostname = malloc(sizeof *hostname);
- if (!hostname)
- die("Insufficient memory to create hostname");
- hostname->hostname = malloc(length + 1);
- if (!hostname->hostname)
- die("Insufficient memory to create hostname");
- memcpy(hostname->hostname, s, length + 1);
- hostname->hostname_length = length;
- hostname->url = 0;
- hostname->previous = last_hostname_found;
- if (!hostname->previous)
- url_store_hostnames = hostname;
- else
- last_hostname_found->next = hostname;
- hostname->next = 0;
- last_hostname_found = hostname;
- } else {
- hostname = url_store_find_hostname(s);
- if (!hostname)
- break;
- }
- if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
- break;
- urls = atoi(s);
-
- /* load the non-corrupt data */
- for (i = 0; i < urls; i++) {
- if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
- break;
- length = strlen(s) - 1;
- s[length] = '\0';
- result = calloc(1, sizeof(struct url_data));
- if (!result)
- die("Insufficient memory to create URL");
- result->data.url_length = length;
- result->data.url = malloc(length + 1);
- if (!result->data.url)
- die("Insufficient memory to create URL");
- memcpy(result->data.url, s, length + 1);
- result->parent = hostname;
- result->next = hostname->url;
- if (hostname->url)
- hostname->url->previous = result;
- hostname->url = result;
- if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
- break;
- result->data.visits = atoi(s);
- if (version == 102) {
- /* ignore requests */
- if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
- break;
- /* ignore thumbnail size */
- if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
- break;
- /* set last visit as today to retain */
- result->data.last_visit = time(NULL);
- } else {
- if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
- break;
- result->data.last_visit = atoi(s);
- if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
- break;
- result->data.type = atoi(s);
- }
- if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
- break;
-#ifdef riscos
- if (strlen(s) == 12) {
- /* ensure filename is 'XX.XX.XX.XX' */
- if ((s[2] == '.') && (s[5] == '.') &&
- (s[8] == '.')) {
- s[11] = '\0';
- result->data.thumbnail =
- bitmap_create_file(s);
- }
- }
-#endif
- if (version >= 104) {
- if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
- break;
- length = strlen(s) - 1;
- if (length > 0) {
- s[length] = '\0';
- result->data.title = malloc(length + 1);
- if (result->data.title)
- memcpy(result->data.title, s,
- length + 1);
- }
- }
- }
- }
- fclose(fp);
- LOG(("Successfully loaded URL file"));
-}
-
-
-/**
- * Saves the current contents of the URL store to disk
- *
- * \param file the file to load options from
- */
-void url_store_save(const char *file) {
- struct hostname_data *search;
- struct url_data *url;
- int url_count;
- const char *thumb_file;
- char *s;
- int i;
- FILE *fp;
-#ifdef riscos
- struct bitmap *bitmap;
-#endif
- time_t min_date;
- char *title;
-
- fp = fopen(file, "w");
- if (!fp) {
- LOG(("Failed to open file '%s' for writing", file));
- return;
- }
-
- /* get the minimum date for expiry */
- min_date = time(NULL) - (60 * 60 * 24) * option_expire_url;
-
- /* file format version number */
- fprintf(fp, "105\n");
- for (search = url_store_hostnames; search; search = search->next) {
- url_count = 0;
- for (url = search->url; url; url = url->next)
- if ((url->data.last_visit > min_date) &&
- (url->data.visits > 0) &&
- (url->data.url_length <
- MAXIMUM_URL_LENGTH)) {
- url_count++;
- }
- if (url_count > 0) {
- fprintf(fp, "%s\n%i\n", search->hostname, url_count);
- for (url = search->url; url && url->next;
- url = url->next);
- for (; url; url = url->previous)
- if ((url->data.last_visit > min_date) &&
- (url->data.visits > 0) &&
- (url->data.url_length <
- MAXIMUM_URL_LENGTH)) {
- thumb_file = "";
-#ifdef riscos
- bitmap = url->data.thumbnail;
- if (bitmap)
- thumb_file = bitmap->filename;
-#endif
-
- if (url->data.title) {
- s = url->data.title;
- for (i = 0; s[i] != '\0';
- i++)
- if (s[i] < 32)
- s[i] = ' ';
- for (--i;
- ((i > 0) &&
- (s[i] == ' '));
- i--)
- s[i] = '\0';
-
- title = url->data.title;
- }
- else
- title = "";
- fprintf(fp, "%s\n%i\n%i\n%i\n%s\n%s\n",
- url->data.url,
- url->data.visits,
- (int) url->data.
- last_visit,
- url->data.type,
- thumb_file,
- title);
- }
- }
- }
- fclose(fp);
-}
-
-
-/**
- * Associates a thumbnail with a specified URL.
- */
-void url_store_add_thumbnail(const char *url, struct bitmap *bitmap) {
- struct url_content *content;
-
- content = url_store_find(url);
- if (content) {
- if (content->thumbnail)
- bitmap_destroy(content->thumbnail);
- content->thumbnail = bitmap;
- }
-}
-
-
-/**
- * Gets the thumbnail associated with a given URL.
- */
-struct bitmap *url_store_get_thumbnail(const char *url) {
- struct url_content *content;
-
- content = url_store_find(url);
- if (content)
- return content->thumbnail;
- return NULL;
-}
-
-
-int url_store_compare_last_visit(const void *a, const void *b) {
- struct url_content * const *url_a = (struct url_content * const *)a;
- struct url_content * const *url_b = (struct url_content * const *)b;
- return ((*url_a)->last_visit - (*url_b)->last_visit);
-}
diff --git a/content/url_store.h b/content/url_store.h
deleted file mode 100644
index c10bc90d0..000000000
--- a/content/url_store.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * This file is part of NetSurf, http://netsurf.sourceforge.net/
- * Licensed under the GNU General Public License,
- * http://www.opensource.org/licenses/gpl-license
- * Copyright 2005 Richard Wilson <info@tinct.net>
- */
-
-/** \file
- * Central repository for URL data (interface).
- */
-
-#ifndef _NETSURF_CONTENT_URLSTORE_H_
-#define _NETSURF_CONTENT_URLSTORE_H_
-
-#include <time.h>
-#include "netsurf/content/content_type.h"
-
-struct bitmap;
-
-
-struct hostname_data {
- char *hostname; /**< Hostname (lowercase) */
- int hostname_length; /**< Length of hostname */
- struct url_data *url; /**< URLs for this host */
- struct hostname_data *previous; /**< Previous hostname */
- struct hostname_data *next; /**< Next hostname */
-};
-
-
-struct url_content {
- struct bitmap *thumbnail; /**< Thumbnail, or NULL */
- char *url; /**< URL (including hostname) */
- char *title; /**< Page title */
- size_t url_length; /**< Length of URL (including hostname) */
- unsigned int visits; /**< Number of times visited */
- time_t last_visit; /**< The time() of the last visit */
- content_type type; /**< The content type */
-};
-
-struct url_data {
- struct url_content data; /**< Stored URL content data */
- struct url_data *previous; /**< Previous URL */
- struct url_data *next; /**< Next URL */
- struct hostname_data *parent; /**< Parent hostname data */
-};
-
-extern struct hostname_data *url_store_hostnames;
-
-struct url_content *url_store_find(const char *url);
-struct url_content *url_store_match(const char *url, struct url_data **reference);
-char *url_store_match_string(const char *text);
-
-void url_store_add_thumbnail(const char *url, struct bitmap *bitmap);
-struct bitmap *url_store_get_thumbnail(const char *url);
-
-void url_store_load(const char *file);
-void url_store_save(const char *file);
-
-int url_store_compare_last_visit(const void *, const void *);
-
-#endif
diff --git a/content/urldb.c b/content/urldb.c
new file mode 100644
index 000000000..c7a798a92
--- /dev/null
+++ b/content/urldb.c
@@ -0,0 +1,2231 @@
+/*
+ * This file is part of NetSurf, http://netsurf.sourceforge.net/
+ * Licensed under the GNU General Public License,
+ * http://www.opensource.org/licenses/gpl-license
+ * Copyright 2006 John M Bell <jmb202@ecs.soton.ac.uk>
+ */
+
+/** \file
+ * Unified URL information database (implementation)
+ *
+ * URLs are stored in a tree-based structure as follows:
+ *
+ * The host component is extracted from each URL and, if a FQDN, split on
+ * every '.'.The tree is constructed by inserting each FQDN segment in
+ * reverse order. Duplicate nodes are merged.
+ *
+ * If the host part of an URL is an IP address, then this is added to the
+ * tree verbatim (as if it were a TLD).
+ *
+ * This provides something looking like:
+ *
+ * root (a sentinel)
+ * |
+ * -------------------------------------------------
+ * | | | | | | |
+ * com edu gov 127.0.0.1 net org uk TLDs
+ * | | | | | |
+ * google ... ... ... ... co 2LDs
+ * | |
+ * www bbc Hosts/Subdomains
+ * |
+ * www ...
+ *
+ * Each of the nodes in this tree is a struct host_part. This stores the
+ * FQDN segment (or IP address) with which the node is concerned. Each node
+ * may contain further information about paths on a host (struct path_data)
+ * or SSL certificate processing on a host-wide basis
+ * (host_part::permit_invalid_certs).
+ *
+ * Path data is concerned with storing various metadata about the path in
+ * question. This includes global history data, HTTP authentication details
+ * and any associated HTTP cookies. This is stored as a tree of path segments
+ * hanging off the relevant host_part node.
+ *
+ * Therefore, to find the last visited time of the URL
+ * http://www.example.com/path/to/resource.html, the FQDN tree would be
+ * traversed in the order root -> "com" -> "example" -> "www". The "www"
+ * node would have attached to it a tree of struct path_data:
+ *
+ * (sentinel)
+ * |
+ * path
+ * |
+ * to
+ * |
+ * resource.html
+ *
+ * This represents the absolute path "/path/to/resource.html". The leaf node
+ * "resource.html" contains the last visited time of the resource.
+ *
+ * The mechanism described above is, however, not particularly conducive to
+ * fast searching of the database for a given URL (or URLs beginning with a
+ * given prefix). Therefore, an anciliary data structure is used to enable
+ * fast searching. This structure simply reflects the contents of the
+ * database, with entries being added/removed at the same time as for the
+ * core database. In order to ensure that degenerate cases are kept to a
+ * minimum, we use an AAtree. This is an approximation of a Red-Black tree
+ * with similar performance characteristics, but with a significantly
+ * simpler implementation. Entries in this tree comprise pointers to the
+ * leaf nodes of the host tree described above.
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "netsurf/image/bitmap.h"
+#include "netsurf/content/urldb.h"
+#include "netsurf/desktop/options.h"
+#ifdef riscos
+/** \todo lose this */
+#include "netsurf/riscos/bitmap.h"
+#endif
+#include "netsurf/utils/log.h"
+#include "netsurf/utils/url.h"
+#include "netsurf/utils/utils.h"
+
+struct cookie {
+ char *name; /**< Cookie name */
+ char *value; /**< Cookie value */
+ char *comment; /**< Cookie comment */
+ time_t expires; /**< Expiry timestamp, or 0 for session */
+ time_t last_used; /**< Last used time */
+ bool secure; /**< Only send for HTTPS requests */
+ enum { COOKIE_NETSCAPE = 0,
+ COOKIE_RFC2109 = 1,
+ COOKIE_RFC2965 = 2
+ } version; /**< Specification compliance */
+ bool no_destroy; /**< Never destroy this cookie,
+ * unless it's expired */
+
+ struct cookie *next; /**< Next in list */
+};
+
+struct auth_data {
+ char *realm; /**< Protection realm */
+ char *auth; /**< Authentication details in form
+ * username:password */
+};
+
+struct url_internal_data {
+ char *title; /**< Resource title */
+ unsigned int visits; /**< Visit count */
+ time_t last_visit; /**< Last visit time */
+ content_type type; /**< Type of resource */
+};
+
+struct path_data {
+ char *scheme; /**< URL scheme for data */
+ unsigned int port; /**< Port number for data */
+ char *segment; /**< Path segment for this node */
+ unsigned int frag_cnt; /**< Number of entries in ::fragment */
+ char **fragment; /**< Array of fragments */
+
+ struct bitmap *thumb; /**< Thumbnail image of resource */
+ struct url_internal_data url; /**< URL data for resource */
+ struct auth_data auth; /**< Authentication data for resource */
+ struct cookie *cookies; /**< Cookies associated with resource */
+
+ struct path_data *next; /**< Next sibling */
+ struct path_data *prev; /**< Previous sibling */
+ struct path_data *parent; /**< Parent path segment */
+ struct path_data *children; /**< Child path segments */
+ struct path_data *last; /**< Last child */
+};
+
+struct host_part {
+ /**< Known paths on this host. This _must_ be first so that
+ * struct host_part *h = (struct host_part *)mypath; works */
+ struct path_data paths;
+ bool permit_invalid_certs; /**< Allow access to SSL protected
+ * resources on this host without
+ * verifying certificate authenticity
+ */
+
+ char *part; /**< Part of host string */
+
+ struct host_part *next; /**< Next sibling */
+ struct host_part *prev; /**< Previous sibling */
+ struct host_part *parent; /**< Parent host part */
+ struct host_part *children; /**< Child host parts */
+};
+
+struct search_node {
+ const struct host_part *data; /**< Host tree entry */
+
+ unsigned int level; /**< Node level */
+
+ struct search_node *left; /**< Left subtree */
+ struct search_node *right; /**< Right subtree */
+};
+
+/* Saving */
+static void urldb_save_search_tree(struct search_node *root, FILE *fp);
+static void urldb_count_urls(const struct path_data *root, time_t expiry,
+ unsigned int *count);
+static void urldb_write_urls(const struct path_data *parent,
+ const char *host, FILE *fp, char **path, int *path_alloc,
+ int *path_used, time_t expiry);
+
+/* Iteration */
+static bool urldb_iterate_partial_host(struct search_node *root,
+ const char *prefix, bool (*callback)(const char *url));
+static bool urldb_iterate_partial_path(const struct path_data *parent,
+ const char *host, const char *prefix,
+ char **path, int *path_alloc, int *path_used,
+ bool (*callback)(const char *url));
+static bool urldb_iterate_entries_host(struct search_node *parent,
+ bool (*callback)(const char *url));
+static bool urldb_iterate_entries_path(const char *host, char **path,
+ int *path_alloc, int *path_used,
+ const struct path_data *parent,
+ bool (*callback)(const char *url));
+
+/* Insertion */
+static struct host_part *urldb_add_host_node(const char *part,
+ struct host_part *parent);
+static struct host_part *urldb_add_host(const char *host);
+static struct path_data *urldb_add_path_node(const char *scheme,
+ unsigned int port, const char *segment, const char *fragment,
+ struct path_data *parent);
+static struct path_data *urldb_add_path(const char *scheme,
+ unsigned int port, const struct host_part *host,
+ const char *path, const char *fragment);
+static int urldb_add_path_fragment_cmp(const void *a, const void *b);
+static struct path_data *urldb_add_path_fragment(struct path_data *segment,
+ const char *fragment);
+
+/* Lookup */
+static struct path_data *urldb_find_url(const char *url);
+static struct path_data *urldb_match_path(const struct path_data *parent,
+ const char *path, const char *scheme, unsigned short port);
+
+/* Dump */
+static void urldb_dump_hosts(struct host_part *parent);
+static void urldb_dump_paths(struct path_data *parent);
+static void urldb_dump_search(struct search_node *parent, int depth);
+
+/* Search tree */
+static struct search_node *urldb_search_insert(struct search_node *root,
+ const struct host_part *data);
+static struct search_node *urldb_search_insert_internal(
+ struct search_node *root, struct search_node *n);
+static struct search_node *urldb_search_remove(struct search_node *root,
+ const struct host_part *data);
+static const struct host_part *urldb_search_find(struct search_node *root,
+ const char *host);
+static struct search_node *urldb_search_skew(struct search_node *root);
+static struct search_node *urldb_search_split(struct search_node *root);
+static int urldb_search_match_host(const struct host_part *a,
+ const struct host_part *b);
+static int urldb_search_match_string(const struct host_part *a,
+ const char *b);
+static int urldb_search_match_prefix(const struct host_part *a,
+ const char *b);
+
+/** Root database handle */
+static struct host_part db_root;
+
+/** Search trees - one per letter + 1 for IPs */
+#define NUM_SEARCH_TREES 27
+#define ST_IP 0
+#define ST_DN 1
+static struct search_node empty = { 0, 0, &empty, &empty };
+static struct search_node *search_trees[NUM_SEARCH_TREES] = {
+ &empty, &empty, &empty, &empty, &empty, &empty, &empty, &empty,
+ &empty, &empty, &empty, &empty, &empty, &empty, &empty, &empty,
+ &empty, &empty, &empty, &empty, &empty, &empty, &empty, &empty,
+ &empty, &empty, &empty
+};
+
+/**
+ * Import an URL database from file, replacing any existing database
+ *
+ * \param filename Name of file containing data
+ */
+void urldb_load(const char *filename)
+{
+#define MAXIMUM_URL_LENGTH 4096
+ char s[MAXIMUM_URL_LENGTH];
+ struct host_part *h;
+ int urls;
+ int i;
+ int version;
+ int length;
+ FILE *fp;
+
+ /** \todo optimise */
+
+ assert(filename);
+
+ LOG(("Loading URL file"));
+
+ fp = fopen(filename, "r");
+ if (!fp) {
+ LOG(("Failed to open file '%s' for reading", filename));
+ return;
+ }
+
+ if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
+ return;
+ version = atoi(s);
+ if (version < 105) {
+ LOG(("Unsupported URL file version."));
+ return;
+ }
+ if (version > 105) {
+ LOG(("Unknown URL file version."));
+ return;
+ }
+
+ while (fgets(s, MAXIMUM_URL_LENGTH, fp)) {
+ /* get the hostname */
+ length = strlen(s) - 1;
+ s[length] = '\0';
+
+ /* skip data that has ended up with a host of '' */
+ if (length == 0) {
+ if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
+ break;
+ urls = atoi(s);
+ for (i = 0; i < (6 * urls); i++)
+ if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
+ break;
+ continue;
+ }
+
+ h = urldb_add_host(s);
+ if (!h)
+ die("Memory exhausted whilst loading URL file");
+
+ if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
+ break;
+ urls = atoi(s);
+
+ /* load the non-corrupt data */
+ for (i = 0; i < urls; i++) {
+ struct path_data *p = NULL;
+
+ if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
+ break;
+ length = strlen(s) - 1;
+ s[length] = '\0';
+
+ urldb_add_url(s);
+ p = urldb_find_url(s);
+
+ if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
+ break;
+ if (p)
+ p->url.visits = (unsigned int)atoi(s);
+
+ if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
+ break;
+ if (p)
+ p->url.last_visit = (time_t)atoi(s);
+
+ if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
+ break;
+ if (p)
+ p->url.type = (content_type)atoi(s);
+
+ if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
+ break;
+#ifdef riscos
+ if (p && strlen(s) == 12) {
+ /* ensure filename is 'XX.XX.XX.XX' */
+ if ((s[2] == '.') && (s[5] == '.') &&
+ (s[8] == '.')) {
+ s[11] = '\0';
+ p->thumb = bitmap_create_file(s);
+ }
+ }
+#endif
+
+ if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
+ break;
+ length = strlen(s) - 1;
+ if (p && length > 0) {
+ s[length] = '\0';
+ p->url.title = malloc(length + 1);
+ if (p->url.title)
+ memcpy(p->url.title, s, length + 1);
+ }
+ }
+ }
+
+ fclose(fp);
+ LOG(("Successfully loaded URL file"));
+#undef MAXIMUM_URL_LENGTH
+}
+
+/**
+ * Export the current database to file
+ *
+ * \param filename Name of file to export to
+ */
+void urldb_save(const char *filename)
+{
+ FILE *fp;
+ int i;
+
+ assert(filename);
+
+ fp = fopen(filename, "w");
+ if (!fp) {
+ LOG(("Failed to open file '%s' for writing", filename));
+ return;
+ }
+
+ /* file format version number */
+ fprintf(fp, "105\n");
+
+ for (i = 0; i != NUM_SEARCH_TREES; i++) {
+ urldb_save_search_tree(search_trees[i], fp);
+ }
+
+ fclose(fp);
+}
+
+/**
+ * Save a search (sub)tree
+ *
+ * \param root Root of (sub)tree to save
+ * \param fp File to write to
+ */
+void urldb_save_search_tree(struct search_node *parent, FILE *fp)
+{
+ char host[256];
+ const struct host_part *h;
+ unsigned int path_count = 0;
+ char *path, *p, *end;
+ int path_alloc = 64, path_used = 2;
+ time_t expiry = time(NULL) - (60 * 60 * 24) * option_expire_url;
+
+ if (parent == &empty)
+ return;
+
+ urldb_save_search_tree(parent->left, fp);
+
+ path = malloc(path_alloc);
+ if (!path)
+ return;
+
+ path[0] = '/';
+ path[1] = '\0';
+
+ for (h = parent->data, p = host, end = host + sizeof host;
+ h && h != &db_root && p < end; h = h->parent) {
+ int written = snprintf(p, end - p, "%s%s", h->part,
+ (h->parent && h->parent->parent) ? "." : "");
+ if (written < 0) {
+ free(path);
+ return;
+ }
+ p += written;
+ }
+
+ urldb_count_urls(&parent->data->paths, expiry, &path_count);
+
+ if (path_count > 0) {
+ fprintf(fp, "%s\n%i\n", host, path_count);
+
+ urldb_write_urls(&parent->data->paths, host, fp,
+ &path, &path_alloc, &path_used, expiry);
+ }
+
+ free(path);
+
+ urldb_save_search_tree(parent->right, fp);
+}
+
+/**
+ * Count number of URLs associated with a host
+ *
+ * \param root Root of path data tree
+ * \param expiry Expiry time for URLs
+ * \param count Pointer to count
+ */
+void urldb_count_urls(const struct path_data *root, time_t expiry,
+ unsigned int *count)
+{
+ const struct path_data *p;
+
+ if (!root->children) {
+ if ((root->url.last_visit > expiry) &&
+ (root->url.visits > 0))
+ (*count)++;
+ }
+
+ for (p = root->children; p; p = p->next)
+ urldb_count_urls(p, expiry, count);
+}
+
+/**
+ * Write URLs associated with a host
+ *
+ * \param parent Root of (sub)tree to write
+ * \param host Current host name
+ * \param fp File to write to
+ * \param path Current path string
+ * \param path_alloc Allocated size of path
+ * \param path_used Used size of path
+ * \param expiry Expiry time of URLs
+ */
+void urldb_write_urls(const struct path_data *parent, const char *host,
+ FILE *fp, char **path, int *path_alloc, int *path_used,
+ time_t expiry)
+{
+ const struct path_data *p;
+ int i;
+ int pused = *path_used;
+
+ if (!parent->children) {
+ /* leaf node */
+ if (!((parent->url.last_visit > expiry) &&
+ (parent->url.visits > 0)))
+ /* expired */
+ return;
+
+ fprintf(fp, "%s://%s", parent->scheme, host);
+
+ if (parent->port)
+ fprintf(fp,":%d", parent->port);
+
+ fprintf(fp, "%s\n", *path);
+
+ /** \todo handle fragments? */
+
+ fprintf(fp, "%i\n%i\n%i\n", parent->url.visits,
+ (int)parent->url.last_visit,
+ (int)parent->url.type);
+
+#ifdef riscos
+ if (parent->thumb)
+ fprintf(fp, "%s\n", parent->thumb->filename);
+#else
+ fprintf(fp, "\n");
+#endif
+
+ if (parent->url.title) {
+ char *s = parent->url.title;
+ for (i = 0; s[i] != '\0'; i++)
+ if (s[i] < 32)
+ s[i] = ' ';
+ for (--i; ((i > 0) && (s[i] == ' ')); i--)
+ s[i] = '\0';
+ fprintf(fp, "%s\n", parent->url.title);
+ } else
+ fprintf(fp, "\n");
+ }
+
+ for (p = parent->children; p; p = p->next) {
+ int len = *path_used + strlen(p->segment) + 1;
+ if (*path_alloc < len) {
+ char *temp = realloc(*path,
+ (len > 64) ? len : *path_alloc + 64);
+ if (!temp)
+ return;
+ *path = temp;
+ *path_alloc = (len > 64) ? len : *path_alloc + 64;
+ }
+
+ strcat(*path, p->segment);
+ if (p->children) {
+ strcat(*path, "/");
+ } else {
+ len -= 1;
+ }
+
+ *path_used = len;
+
+ urldb_write_urls(p, host, fp, path, path_alloc, path_used,
+ expiry);
+
+ /* restore path to its state on entry to this function */
+ *path_used = pused;
+ (*path)[pused - 1] = '\0';
+ }
+}
+
+/**
+ * Insert an URL into the database
+ *
+ * \param url URL to insert
+ * \return true on success, false otherwise
+ */
+bool urldb_add_url(const char *url)
+{
+ struct host_part *h;
+ struct path_data *p;
+ char *fragment = NULL, *host, *plq, *scheme, *colon;
+ unsigned short port;
+ url_func_result ret;
+ assert(url);
+
+ /** \todo consider file: URLs */
+
+ host = strchr(url, '#');
+ if (host) {
+ fragment = strdup(host+1);
+ if (!fragment)
+ return false;
+ }
+
+ /* extract host */
+ ret = url_host(url, &host);
+ if (ret != URL_FUNC_OK)
+ return false;
+
+ /* extract path, leafname, query */
+ ret = url_plq(url, &plq);
+ if (ret != URL_FUNC_OK) {
+ free(host);
+ free(fragment);
+ return false;
+ }
+
+ /* extract scheme */
+ ret = url_scheme(url, &scheme);
+ if (ret != URL_FUNC_OK) {
+ free(plq);
+ free(host);
+ free(fragment);
+ return false;
+ }
+
+ colon = strrchr(host, ':');
+ if (!colon) {
+ port = 0;
+ } else {
+ *colon = '\0';
+ port = atoi(colon + 1);
+ }
+
+ /* Get host entry */
+ h = urldb_add_host(host);
+ if (!h) {
+ free(scheme);
+ free(plq);
+ free(host);
+ free(fragment);
+ return false;
+ }
+
+ /* Get path entry */
+ p = urldb_add_path(scheme, port, h, plq, fragment);
+ if (!p) {
+ free(scheme);
+ free(plq);
+ free(host);
+ free(fragment);
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Set an URL's title string, replacing any existing one
+ *
+ * \param url The URL to look for
+ * \param title The title string to use (copied)
+ */
+void urldb_set_url_title(const char *url, const char *title)
+{
+ struct path_data *p;
+ char *temp;
+
+ assert(url && title);
+
+ p = urldb_find_url(url);
+ if (!p)
+ return;
+
+ temp = strdup(title);
+ if (!temp)
+ return;
+
+ free(p->url.title);
+ p->url.title = temp;
+}
+
+/**
+ * Set an URL's content type
+ *
+ * \param url The URL to look for
+ * \param type The type to set
+ */
+void urldb_set_url_content_type(const char *url, content_type type)
+{
+ struct path_data *p;
+
+ assert(url);
+
+ p = urldb_find_url(url);
+ if (!p)
+ return;
+
+ p->url.type = type;
+}
+
+/**
+ * Update an URL's visit data
+ *
+ * \param url The URL to update
+ */
+void urldb_update_url_visit_data(const char *url)
+{
+ struct path_data *p;
+
+ assert(url);
+
+ p = urldb_find_url(url);
+ if (!p)
+ return;
+
+ p->url.last_visit = time(NULL);
+ p->url.visits++;
+}
+
+/**
+ * Reset an URL's visit statistics
+ *
+ * \param url The URL to reset
+ */
+void urldb_reset_url_visit_data(const char *url)
+{
+ struct path_data *p;
+
+ assert(url);
+
+ p = urldb_find_url(url);
+ if (!p)
+ return;
+
+ p->url.last_visit = (time_t)0;
+ p->url.visits = 0;
+}
+
+
+/**
+ * Find data for an URL.
+ *
+ * \param url Absolute URL to look for
+ * \return Pointer to result struct, or NULL
+ */
+const struct url_data *urldb_get_url_data(const char *url)
+{
+ struct path_data *p;
+
+ assert(url);
+
+ p = urldb_find_url(url);
+ if (!p)
+ return NULL;
+
+ return (struct url_data *)&p->url;
+}
+
+/**
+ * Look up authentication details in database
+ *
+ * \param url Absolute URL to search for
+ * \return Pointer to authentication details, or NULL if not found
+ */
+const char *urldb_get_auth_details(const char *url)
+{
+ struct path_data *p, *q;
+
+ assert(url);
+
+ /* add to the db, so our lookup will work */
+ urldb_add_url(url);
+
+ p = urldb_find_url(url);
+ if (!p)
+ return NULL;
+
+ for (; p; p = p->parent) {
+ /* The parent path entry is stored hung off the
+ * parent entry with an empty (not NULL) segment string.
+ * We look for this here.
+ */
+ for (q = p->children; q; q = q->next) {
+ if (strlen(q->segment) == 0)
+ break;
+ }
+
+ if (q && q->auth.realm && q->auth.auth)
+ break;
+ }
+
+ if (!q)
+ return NULL;
+
+ return q->auth.auth;
+}
+
+/**
+ * Retrieve certificate verification permissions from database
+ *
+ * \param url Absolute URL to search for
+ * \return true to permit connections to hosts with invalid certificates,
+ * false otherwise.
+ */
+bool urldb_get_cert_permissions(const char *url)
+{
+ struct path_data *p;
+ struct host_part *h;
+
+ assert(url);
+
+ p = urldb_find_url(url);
+ if (!p)
+ return false;
+
+ for (; p && p->parent; p = p->parent)
+ /* do nothing */;
+
+ h = (struct host_part *)p;
+
+ return h->permit_invalid_certs;
+}
+
+/**
+ * Set authentication data for an URL
+ *
+ * \param url The URL to consider
+ * \param realm The authentication realm
+ * \param auth The authentication details (in form username:password)
+ */
+void urldb_set_auth_details(const char *url, const char *realm,
+ const char *auth)
+{
+ struct path_data *p;
+ char *t1, *t2;
+
+ assert(url && realm && auth);
+
+ /* add url, in case it's missing */
+ urldb_add_url(url);
+
+ p = urldb_find_url(url);
+ if (!p)
+ return;
+
+ /** \todo search subtree for same realm/auth details
+ * and remove them (as the lookup routine searches up the tree) */
+
+ t1 = strdup(realm);
+ t2 = strdup(auth);
+
+ if (!t1 || !t2) {
+ free(t1);
+ free(t2);
+ return;
+ }
+
+ free(p->auth.realm);
+ free(p->auth.auth);
+
+ p->auth.realm = t1;
+ p->auth.auth = t2;
+}
+
+/**
+ * Set certificate verification permissions
+ *
+ * \param url URL to consider
+ * \param permit Set to true to allow invalid certificates
+ */
+void urldb_set_cert_permissions(const char *url, bool permit)
+{
+ struct path_data *p;
+ struct host_part *h;
+
+ assert(url);
+
+ /* add url, in case it's missing */
+ urldb_add_url(url);
+
+ p = urldb_find_url(url);
+ if (!p)
+ return;
+
+ for (; p && p->parent; p = p->parent)
+ /* do nothing */;
+
+ h = (struct host_part *)p;
+
+ h->permit_invalid_certs = permit;
+}
+
+/**
+ * Set thumbnail for url, replacing any existing thumbnail
+ *
+ * \param url Absolute URL to consider
+ * \param bitmap Opaque pointer to thumbnail data
+ */
+void urldb_set_thumbnail(const char *url, struct bitmap *bitmap)
+{
+ struct path_data *p;
+
+ assert(url && bitmap);
+
+ p = urldb_find_url(url);
+ if (!p)
+ return;
+
+ if (p->thumb)
+ bitmap_destroy(p->thumb);
+
+ p->thumb = bitmap;
+}
+
+/**
+ * Retrieve thumbnail data for given URL
+ *
+ * \param url Absolute URL to search for
+ * \return Pointer to thumbnail data, or NULL if not found.
+ */
+const struct bitmap *urldb_get_thumbnail(const char *url)
+{
+ struct path_data *p;
+
+ assert(url);
+
+ p = urldb_find_url(url);
+ if (!p)
+ return NULL;
+
+ return p->thumb;
+}
+
+/**
+ * Iterate over entries in the database which match the given prefix
+ *
+ * \param prefix Prefix to match
+ * \param callback Callback function
+ */
+void urldb_iterate_partial(const char *prefix,
+ bool (*callback)(const char *url))
+{
+ char host[256];
+ char buf[260]; /* max domain + "www." */
+ const char *slash;
+ struct search_node *tree;
+ const struct host_part *h;
+
+ assert(prefix && callback);
+
+ slash = strchr(prefix, '/');
+
+ if (*prefix >= '0' && *prefix <= '9')
+ tree = search_trees[ST_IP];
+ else if (isalpha(*prefix))
+ tree = search_trees[ST_DN + tolower(*prefix) - 'a'];
+ else
+ return;
+
+ if (slash) {
+ /* if there's a slash in the input, then we can
+ * assume that we're looking for a path */
+ char *path, *domain = host;
+ int path_alloc = 64, path_used = 2;
+
+ snprintf(host, sizeof host, "%.*s", slash - prefix, prefix);
+
+ h = urldb_search_find(tree, host);
+ if (!h) {
+ int len = slash - prefix;
+
+ if ((len == 1 && tolower(host[0]) != 'w') ||
+ (len == 2 && (tolower(host[0]) != 'w' ||
+ tolower(host[1]) != 'w')) ||
+ (len >= 3 &&
+ strncasecmp(host, "www", 3))) {
+ snprintf(buf, sizeof buf, "www.%s", host);
+ h = urldb_search_find(
+ search_trees[ST_DN + 'w' - 'a'],
+ buf);
+ if (!h)
+ return;
+ domain = buf;
+ } else
+ return;
+ }
+
+ path = malloc(path_alloc);
+ if (!path)
+ return;
+
+ path[0] = '/';
+ path[1] = '\0';
+
+ urldb_iterate_partial_path(&h->paths, domain, slash + 1,
+ &path, &path_alloc, &path_used, callback);
+
+ free(path);
+ } else {
+ int len = strlen(prefix);
+
+ /* looking for hosts */
+ if (!urldb_iterate_partial_host(tree, prefix, callback))
+ return;
+
+ if ((len == 1 && tolower(prefix[0]) != 'w') ||
+ (len == 2 && (tolower(prefix[0]) != 'w' ||
+ tolower(prefix[1]) != 'w')) ||
+ (len >= 3 &&
+ strncasecmp(prefix, "www", 3))) {
+ /* now look for www.prefix */
+ snprintf(buf, sizeof buf, "www.%s", prefix);
+ if(!urldb_iterate_partial_host(
+ search_trees[ST_DN + 'w' - 'a'],
+ buf, callback))
+ return;
+ }
+ }
+}
+
+/**
+ * Partial host iterator (internal)
+ *
+ * \param root Root of (sub)tree to traverse
+ * \param prefix Prefix to match
+ * \param callback Callback function
+ * \return true to continue, false otherwise
+ */
+bool urldb_iterate_partial_host(struct search_node *root, const char *prefix,
+ bool (*callback)(const char *url))
+{
+ int c;
+ const struct host_part *h;
+ char domain[256], *p, *end;
+ char *path;
+ int path_alloc = 64, path_used = 2;
+
+ assert(root && prefix && callback);
+
+ if (root == &empty)
+ return true;
+
+ c = urldb_search_match_prefix(root->data, prefix);
+
+ if (c > 0)
+ /* No match => look in left subtree */
+ return urldb_iterate_partial_host(root->left, prefix,
+ callback);
+ else if (c < 0)
+ /* No match => look in right subtree */
+ return urldb_iterate_partial_host(root->right, prefix,
+ callback);
+ else {
+ /* Match => iterate over l/r subtrees & process this node */
+ if (!urldb_iterate_partial_host(root->left, prefix,
+ callback))
+ return false;
+
+ /* Generate host string */
+ for (h = root->data, p = domain,
+ end = domain + sizeof domain;
+ h && h != &db_root && p < end;
+ h = h->parent) {
+ int written = snprintf(p, end - p, "%s%s", h->part,
+ (h->parent && h->parent->parent) ? "." : "");
+ if (written < 0)
+ return false;
+ p += written;
+ }
+
+ path = malloc(path_alloc);
+ if (!path)
+ return false;
+
+ path[0] = '/';
+ path[1] = '\0';
+
+ /* and extract all paths attached to this host */
+ if (!urldb_iterate_entries_path(domain, &path, &path_alloc,
+ &path_used, &root->data->paths, callback)) {
+ free(path);
+ return false;
+ }
+
+ free(path);
+
+ if (!urldb_iterate_partial_host(root->right, prefix,
+ callback))
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Partial path iterator (internal)
+ *
+ * \param parent Root of (sub)tree to traverse
+ * \param host Host string
+ * \param prefix Prefix to match
+ * \param path The built path up to this point
+ * \param path_alloc Allocated size of path
+ * \param path_used Used size of path
+ * \param callback Callback function
+ * \return true to continue, false otherwise
+ */
+bool urldb_iterate_partial_path(const struct path_data *parent,
+ const char *host, const char *prefix,
+ char **path, int *path_alloc, int *path_used,
+ bool (*callback)(const char *url))
+{
+ const struct path_data *p;
+ const char *slash, *end = prefix + strlen(prefix);
+ int pused = *path_used;
+ int c;
+
+ slash = strchr(prefix, '/');
+ if (!slash)
+ slash = end;
+
+ if (slash == prefix && *prefix == '/')
+ /* Ignore "//" */
+ return true;
+
+ for (p = parent->children; p; p = p->next) {
+ if ((c = strncasecmp(p->segment, prefix, slash - prefix)) < 0)
+ /* didn't match, but may be more */
+ continue;
+ else if (c > 0)
+ /* no more possible matches */
+ break;
+
+ /* prefix matches so far */
+ int len = *path_used + strlen(p->segment) + 1;
+ if (*path_alloc < len) {
+ char *temp = realloc(*path,
+ (len > 64) ? len : *path_alloc + 64);
+ if (!temp)
+ return false;
+ *path = temp;
+ *path_alloc = (len > 64) ? len : *path_alloc + 64;
+ }
+
+ strcat(*path, p->segment);
+ if (p->children)
+ strcat(*path, "/");
+ else
+ len -= 1;
+
+ *path_used = len;
+
+ if (slash == end) {
+ /* we've run out of prefix, so all
+ * paths below this one match */
+ if (!urldb_iterate_entries_path(host, path,
+ path_alloc, path_used, p, callback))
+ return false;
+ } else {
+ /* more prefix to go => recurse */
+ if (!urldb_iterate_partial_path(p, host, slash + 1,
+ path, path_alloc, path_used,
+ callback))
+ return false;
+ }
+
+ /* restore path to that from input for next child */
+ *path_used = pused;
+ (*path)[pused - 1] = '\0';
+ }
+
+ return true;
+}
+
+/**
+ * Iterate over all entries in database
+ *
+ * \param callback Function to callback for each entry
+ */
+void urldb_iterate_entries(bool (*callback)(const char *url))
+{
+ int i;
+
+ assert(callback);
+
+ for (i = 0; i < NUM_SEARCH_TREES; i++) {
+ if (!urldb_iterate_entries_host(search_trees[i],
+ callback))
+ break;
+ }
+}
+
+/**
+ * Host data iterator (internal)
+ *
+ * \param parent Root of subtree to iterate over
+ * \param callback Callback function
+ * \return true to continue, false otherwise
+ */
+bool urldb_iterate_entries_host(struct search_node *parent,
+ bool (*callback)(const char *url))
+{
+ char domain[256], *p, *end;
+ const struct host_part *h;
+ char *path;
+ int path_alloc = 64, path_used = 2;
+
+ if (parent == &empty)
+ return true;
+
+ if (!urldb_iterate_entries_host(parent->left, callback))
+ return false;
+
+ for (h = parent->data, p = domain, end = domain + sizeof domain;
+ h && h != &db_root && p < end; h = h->parent) {
+ int written = snprintf(p, end - p, "%s%s", h->part,
+ (h->parent && h->parent->parent) ? "." : "");
+ if (written < 0)
+ return false;
+ p += written;
+ }
+
+ path = malloc(path_alloc);
+ if (!path)
+ return false;
+
+ path[0] = '/';
+ path[1] = '\0';
+
+ if (!urldb_iterate_entries_path(domain, &path, &path_alloc,
+ &path_used, &parent->data->paths, callback)) {
+ free(path);
+ return false;
+ }
+
+ free(path);
+
+ if (!urldb_iterate_entries_host(parent->right, callback))
+ return false;
+
+ return true;
+}
+
+/**
+ * Path data iterator (internal)
+ *
+ * \param host Host component of output URI
+ * \param path The built path up to this point
+ * \param path_alloc Allocated size of path
+ * \param path_used Used size of path
+ * \param parent Root of subtree to iterate over
+ * \param callback Callback function to call
+ * \return true to continue, false otherwise
+ */
+bool urldb_iterate_entries_path(const char *host, char **path,
+ int *path_alloc, int *path_used,
+ const struct path_data *parent,
+ bool (*callback)(const char *url))
+{
+ const struct path_data *p;
+ int pused = *path_used;
+
+ if (!parent->children) {
+ /* leaf node */
+ int schemelen = strlen(parent->scheme);
+ int hostlen = strlen(host);
+ int prefixlen = schemelen + 3 /* :// */ +
+ hostlen + 6 /* :NNNNN */;
+ static char *url;
+ static int url_alloc;
+ int written;
+
+ if (url_alloc < *path_used + prefixlen + 2) {
+ char *temp = realloc(url, *path_used + prefixlen + 2);
+ if (!temp)
+ return false;
+ url = temp;
+ url_alloc = *path_used + prefixlen + 2;
+ }
+
+ written = sprintf(url, "%s://%s", parent->scheme, host);
+ if (written < 0) {
+ return false;
+ }
+
+ if (parent->port) {
+ written = sprintf(url + schemelen + 3 + hostlen,
+ ":%d", parent->port);
+ if (written < 0) {
+ return false;
+ }
+ written += schemelen + 3 + hostlen;
+ }
+
+ written = sprintf(url + written, "%s", *path);
+ if (written < 0) {
+ return false;
+ }
+
+ /** \todo handle fragments? */
+
+ if (!callback(url))
+ return false;
+ }
+
+ for (p = parent->children; p; p = p->next) {
+ int len = *path_used + strlen(p->segment) + 1;
+ if (*path_alloc < len) {
+ char *temp = realloc(*path,
+ (len > 64) ? len : *path_alloc + 64);
+ if (!temp)
+ return false;
+ *path = temp;
+ *path_alloc = (len > 64) ? len : *path_alloc + 64;
+ }
+
+ strcat(*path, p->segment);
+ if (p->children) {
+ strcat(*path, "/");
+ } else {
+ len -= 1;
+ }
+
+ *path_used = len;
+
+ if (!urldb_iterate_entries_path(host, path, path_alloc,
+ path_used, p, callback))
+ return false;
+
+ /* restore path to its state on entry to this function */
+ *path_used = pused;
+ (*path)[pused - 1] = '\0';
+ }
+
+ return true;
+}
+
+/**
+ * Add a host node to the tree
+ *
+ * \param part Host segment to add (or whole IP address) (copied)
+ * \param parent Parent node to add to
+ * \return Pointer to added node, or NULL on memory exhaustion
+ */
+struct host_part *urldb_add_host_node(const char *part,
+ struct host_part *parent)
+{
+ struct host_part *d;
+
+ assert(part && parent);
+
+ d = calloc(1, sizeof(struct host_part));
+ if (!d)
+ return NULL;
+
+ d->part = strdup(part);
+ if (!d->part) {
+ free(d);
+ return NULL;
+ }
+
+ d->next = parent->children;
+ if (parent->children)
+ parent->children->prev = d;
+ d->parent = parent;
+ parent->children = d;
+
+ return d;
+}
+
+/**
+ * Add a host to the database, creating any intermediate entries
+ *
+ * \param host Hostname to add
+ * \return Pointer to leaf node, or NULL on memory exhaustion
+ */
+struct host_part *urldb_add_host(const char *host)
+{
+ struct host_part *d = (struct host_part *) &db_root, *e;
+ struct search_node *s;
+ char buf[256]; /* 256 bytes is sufficient - domain names are
+ * limited to 255 chars. */
+ char *part;
+
+ assert(host);
+
+ if (*(host) >= '0' && *(host) <= '9') {
+ /* Host is an IP, so simply add as TLD */
+
+ /* Check for existing entry */
+ for (e = d->children; e; e = e->next)
+ if (strcasecmp(host, e->part) == 0)
+ /* found => return it */
+ return e;
+
+ d = urldb_add_host_node(host, d);
+
+ s = urldb_search_insert(search_trees[ST_IP], d);
+ if (!s) {
+ /* failed */
+ d = NULL;
+ } else {
+ search_trees[ST_IP] = s;
+ }
+
+ return d;
+ }
+
+ /* Copy host string, so we can corrupt it */
+ strncpy(buf, host, sizeof buf);
+ buf[sizeof buf - 1] = '\0';
+
+ /* Process FQDN segments backwards */
+ do {
+ part = strrchr(buf, '.');
+ if (!part) {
+ /* last segment */
+ /* Check for existing entry */
+ for (e = d->children; e; e = e->next)
+ if (strcasecmp(buf, e->part) == 0)
+ break;
+
+ if (e) {
+ d = e;
+ } else {
+ d = urldb_add_host_node(buf, d);
+ }
+
+ /* And insert into search tree */
+ if (d) {
+ if (isalpha(*buf)) {
+ struct search_node **r;
+ r = &search_trees[
+ tolower(*buf) - 'a' + ST_DN];
+
+ s = urldb_search_insert(*r, d);
+ if (!s) {
+ /* failed */
+ d = NULL;
+ } else {
+ *r = s;
+ }
+ } else {
+ d = NULL;
+ }
+ }
+ break;
+ }
+
+ /* Check for existing entry */
+ for (e = d->children; e; e = e->next)
+ if (strcasecmp(part + 1, e->part) == 0)
+ break;
+
+ d = e ? e : urldb_add_host_node(part + 1, d);
+ if (!d)
+ break;
+
+ *part = '\0';
+ } while (1);
+
+ return d;
+}
+
+/**
+ * Add a path node to the tree
+ *
+ * \param scheme URL scheme associated with path (copied)
+ * \param port Port number on host associated with path
+ * \param segment Path segment to add (copied)
+ * \param fragment URL fragment (copied), or NULL
+ * \param parent Parent node to add to
+ * \return Pointer to added node, or NULL on memory exhaustion
+ */
+struct path_data *urldb_add_path_node(const char *scheme, unsigned int port,
+ const char *segment, const char *fragment,
+ struct path_data *parent)
+{
+ struct path_data *d, *e;
+
+ assert(scheme && segment && parent);
+
+ d = calloc(1, sizeof(struct path_data));
+ if (!d)
+ return NULL;
+
+ d->scheme = strdup(scheme);
+ if (!d->scheme) {
+ free(d);
+ return NULL;
+ }
+
+ d->port = port;
+
+ d->segment = strdup(segment);
+ if (!d->segment) {
+ free(d->scheme);
+ free(d);
+ return NULL;
+ }
+
+ if (fragment) {
+ if (!urldb_add_path_fragment(d, fragment)) {
+ free(d->segment);
+ free(d->scheme);
+ free(d);
+ return NULL;
+ }
+ }
+
+ for (e = parent->children; e; e = e->next)
+ if (strcmp(e->segment, d->segment) > 0)
+ break;
+
+ if (e) {
+ d->prev = e->prev;
+ d->next = e;
+ if (e->prev)
+ e->prev->next = d;
+ else
+ parent->children = d;
+ e->prev = d;
+ } else if (!parent->children) {
+ d->prev = d->next = NULL;
+ parent->children = parent->last = d;
+ } else {
+ d->next = NULL;
+ d->prev = parent->last;
+ parent->last->next = d;
+ parent->last = d;
+ }
+ d->parent = parent;
+
+ return d;
+}
+
+/**
+ * Add a path to the database, creating any intermediate entries
+ *
+ * \param scheme URL scheme associated with path
+ * \param port Port number on host associated with path
+ * \param host Host tree node to attach to
+ * \param path Absolute path to add
+ * \param fragment URL fragment, or NULL
+ * \return Pointer to leaf node, or NULL on memory exhaustion
+ */
+struct path_data *urldb_add_path(const char *scheme, unsigned int port,
+ const struct host_part *host, const char *path,
+ const char *fragment)
+{
+ struct path_data *d, *e;
+ char *buf;
+ char *segment, *slash;
+
+ assert(scheme && host && path);
+
+ d = (struct path_data *) &host->paths;
+
+ /* Copy path string, so we can corrupt it */
+ buf = malloc(strlen(path) + 1);
+ if (!buf)
+ return NULL;
+
+ /* + 1 to strip leading '/' */
+ strcpy(buf, path + 1);
+
+ segment = buf;
+
+ /* Process path segments */
+ do {
+ slash = strchr(segment, '/');
+ if (!slash) {
+ /* last segment */
+ /* look for existing entry */
+ for (e = d->children; e; e = e->next)
+ if (strcmp(segment, e->segment) == 0 &&
+ strcasecmp(scheme,
+ e->scheme) == 0 &&
+ e->port == port)
+ break;
+
+ d = e ? urldb_add_path_fragment(e, fragment) :
+ urldb_add_path_node(scheme, port,
+ segment, fragment, d);
+ break;
+ }
+
+ *slash = '\0';
+
+ /* look for existing entry */
+ for (e = d->children; e; e = e->next)
+ if (strcmp(segment, e->segment) == 0 &&
+ strcasecmp(scheme, e->scheme) == 0 &&
+ e->port == port)
+ break;
+
+ d = e ? e : urldb_add_path_node(scheme, port, segment,
+ NULL, d);
+ if (!d)
+ break;
+
+ segment = slash + 1;
+ } while (1);
+
+ free(buf);
+
+ return d;
+}
+
+/**
+ * Fragment comparator callback for qsort
+ */
+int urldb_add_path_fragment_cmp(const void *a, const void *b)
+{
+ return strcasecmp(*((const char **) a), *((const char **) b));
+}
+
+/**
+ * Add a fragment to a path segment
+ *
+ * \param segment Path segment to add to
+ * \param fragment Fragment to add (copied), or NULL
+ * \return segment or NULL on memory exhaustion
+ */
+struct path_data *urldb_add_path_fragment(struct path_data *segment,
+ const char *fragment)
+{
+ char **temp;
+
+ assert(segment);
+
+ /* If no fragment, this function is a NOP
+ * This may seem strange, but it makes the rest
+ * of the code cleaner */
+ if (!fragment)
+ return segment;
+
+ temp = realloc(segment->fragment,
+ (segment->frag_cnt + 1) * sizeof(char *));
+ if (!temp)
+ return NULL;
+
+ segment->fragment = temp;
+ segment->fragment[segment->frag_cnt] = strdup(fragment);
+ if (!segment->fragment[segment->frag_cnt]) {
+ /* Don't free temp - it's now our buffer */
+ return NULL;
+ }
+
+ segment->frag_cnt++;
+
+ /* We want fragments in alphabetical order, so sort them
+ * It may prove better to insert in alphabetical order instead */
+ qsort(segment->fragment, segment->frag_cnt, sizeof (char *),
+ urldb_add_path_fragment_cmp);
+
+ return segment;
+}
+
+/**
+ * Find an URL in the database
+ *
+ * \param url The URL to find
+ * \return Pointer to path data, or NULL if not found
+ */
+struct path_data *urldb_find_url(const char *url)
+{
+ const struct host_part *h;
+ struct path_data *p;
+ struct search_node *tree;
+ char *host, *plq, *scheme, *colon;
+ unsigned short port;
+ url_func_result ret;
+
+ assert(url);
+
+ /** \todo consider file: URLs */
+
+ /* extract host */
+ ret = url_host(url, &host);
+ if (ret != URL_FUNC_OK)
+ return NULL;
+
+ /* extract path, leafname, query */
+ ret = url_plq(url, &plq);
+ if (ret != URL_FUNC_OK) {
+ free(host);
+ return NULL;
+ }
+
+ /* extract scheme */
+ ret = url_scheme(url, &scheme);
+ if (ret != URL_FUNC_OK) {
+ free(plq);
+ free(host);
+ return NULL;
+ }
+
+ colon = strrchr(host, ':');
+ if (!colon) {
+ port = 0;
+ } else {
+ *colon = '\0';
+ port = atoi(colon + 1);
+ }
+
+ if (*host >= '0' && *host <= '9')
+ tree = search_trees[ST_IP];
+ else if (isalpha(*host))
+ tree = search_trees[ST_DN + tolower(*host) - 'a'];
+ else {
+ free(plq);
+ free(host);
+ free(scheme);
+ return NULL;
+ }
+
+ h = urldb_search_find(tree, host);
+ if (!h) {
+ free(plq);
+ free(host);
+ free(scheme);
+ return NULL;
+ }
+
+ p = urldb_match_path(&h->paths, plq, scheme, port);
+
+ free(plq);
+ free(host);
+ free(scheme);
+
+ return p;
+}
+
+/**
+ * Match a path string
+ *
+ * \param parent Path (sub)tree to look in
+ * \param path The path to search for
+ * \param scheme The URL scheme associated with the path
+ * \param port The port associated with the path
+ * \return Pointer to path data or NULL if not found.
+ */
+struct path_data *urldb_match_path(const struct path_data *parent,
+ const char *path, const char *scheme, unsigned short port)
+{
+ struct path_data *p;
+ const char *slash;
+
+ if (*path == '\0')
+ return (struct path_data *)parent;
+
+ slash = strchr(path + 1, '/');
+ if (!slash)
+ slash = path + strlen(path);
+
+ for (p = parent->children; p; p = p->next) {
+ if (strncmp(p->segment, path + 1, slash - path - 1) == 0 &&
+ strcmp(p->scheme, scheme) == 0 &&
+ p->port == port)
+ break;
+ }
+
+ if (p) {
+ return urldb_match_path(p, slash, scheme, port);
+ }
+
+ return NULL;
+}
+
+/**
+ * Dump URL database to stderr
+ */
+void urldb_dump(void)
+{
+ int i;
+
+ urldb_dump_hosts(&db_root);
+
+ for (i = 0; i != NUM_SEARCH_TREES; i++)
+ urldb_dump_search(search_trees[i], 0);
+}
+
+/**
+ * Dump URL database hosts to stderr
+ *
+ * \param parent Parent node of tree to dump
+ */
+void urldb_dump_hosts(struct host_part *parent)
+{
+ struct host_part *h;
+
+ if (parent->part) {
+ LOG(("%s", parent->part));
+
+ LOG(("\t%s invalid SSL certs",
+ parent->permit_invalid_certs ? "Permits" : "Denies"));
+ }
+
+ /* Dump path data */
+ urldb_dump_paths(&parent->paths);
+
+ /* and recurse */
+ for (h = parent->children; h; h = h->next)
+ urldb_dump_hosts(h);
+}
+
+/**
+ * Dump URL database paths to stderr
+ *
+ * \param parent Parent node of tree to dump
+ */
+void urldb_dump_paths(struct path_data *parent)
+{
+ struct path_data *p;
+ unsigned int i;
+
+ if (parent->segment) {
+ LOG(("\t%s : %u", parent->scheme, parent->port));
+
+ LOG(("\t\t'%s'", parent->segment));
+
+ for (i = 0; i != parent->frag_cnt; i++)
+ LOG(("\t\t\t#%s", parent->fragment[i]));
+ }
+
+ /* and recurse */
+ for (p = parent->children; p; p = p->next)
+ urldb_dump_paths(p);
+}
+
+/**
+ * Dump search tree
+ *
+ * \param parent Parent node of tree to dump
+ * \param depth Tree depth
+ */
+void urldb_dump_search(struct search_node *parent, int depth)
+{
+ const struct host_part *h;
+ int i;
+
+ if (parent == &empty)
+ return;
+
+ urldb_dump_search(parent->left, depth + 1);
+
+ for (i = 0; i != depth; i++)
+ fputc(' ', stderr);
+
+ for (h = parent->data; h; h = h->parent) {
+ fprintf(stderr, "%s", h->part);
+ if (h->parent && h->parent->parent)
+ fputc('.', stderr);
+ }
+
+ fputc('\n', stderr);
+
+ urldb_dump_search(parent->right, depth + 1);
+}
+
+/**
+ * Insert a node into the search tree
+ *
+ * \param root Root of tree to insert into
+ * \param data User data to insert
+ * \return Pointer to updated root, or NULL if failed
+ */
+struct search_node *urldb_search_insert(struct search_node *root,
+ const struct host_part *data)
+{
+ struct search_node *n;
+
+ assert(root && data);
+
+ n = malloc(sizeof(struct search_node));
+ if (!n)
+ return NULL;
+
+ n->level = 1;
+ n->data = data;
+ n->left = n->right = &empty;
+
+ root = urldb_search_insert_internal(root, n);
+
+ return root;
+}
+
+/**
+ * Insert node into search tree
+ *
+ * \param root Root of (sub)tree to insert into
+ * \param n Node to insert
+ * \return Pointer to updated root
+ */
+struct search_node *urldb_search_insert_internal(struct search_node *root,
+ struct search_node *n)
+{
+ assert(root && n);
+
+ if (root == &empty) {
+ root = n;
+ } else {
+ int c = urldb_search_match_host(root->data, n->data);
+
+ if (c > 0) {
+ root->left = urldb_search_insert_internal(
+ root->left, n);
+ } else if (c < 0) {
+ root->right = urldb_search_insert_internal(
+ root->right, n);
+ } else {
+ /* exact match */
+ free(n);
+ return root;
+ }
+
+ root = urldb_search_skew(root);
+ root = urldb_search_split(root);
+ }
+
+ return root;
+}
+
+/**
+ * Delete a node from a search tree
+ *
+ * \param root Tree to remove from
+ * \param data Data to delete
+ * \return Updated root of tree
+ */
+struct search_node *urldb_search_remove(struct search_node *root,
+ const struct host_part *data)
+{
+ static struct search_node *last, *deleted;
+
+ assert(root && data);
+
+ if (root != &empty) {
+ int c = urldb_search_match_host(root->data, data);
+
+ last = root;
+ if (c > 0) {
+ root->left = urldb_search_remove(root->left, data);
+ } else {
+ deleted = root;
+ root->right = urldb_search_remove(root->right, data);
+ }
+ }
+
+ if (root == last) {
+ if (deleted != &empty &&
+ urldb_search_match_host(deleted->data,
+ data) == 0) {
+ deleted->data = last->data;
+ deleted = &empty;
+ root = root->right;
+ }
+ } else {
+ if (root->left->level < root->level - 1 ||
+ root->right->level < root->level - 1) {
+ if (root->right->level > --root->level)
+ root->right->level = root->level;
+
+ root = urldb_search_skew(root);
+ root->right = urldb_search_skew(root->right);
+ root->right->right =
+ urldb_search_skew(root->right->right);
+ root = urldb_search_split(root);
+ root->right = urldb_search_split(root->right);
+ }
+ }
+
+ return root;
+}
+
+/**
+ * Find a node in a search tree
+ *
+ * \param root Tree to look in
+ * \param host Host to find
+ * \return Pointer to host tree node, or NULL if not found
+ */
+const struct host_part *urldb_search_find(struct search_node *root,
+ const char *host)
+{
+ int c;
+
+ assert(root && host);
+
+ if (root == &empty) {
+ return NULL;
+ }
+
+ c = urldb_search_match_string(root->data, host);
+
+ if (c > 0)
+ return urldb_search_find(root->left, host);
+ else if (c < 0)
+ return urldb_search_find(root->right, host);
+ else
+ return root->data;
+}
+
+/**
+ * Compare a pair of host_parts
+ *
+ * \param a
+ * \param b
+ * \return 0 if match, non-zero, otherwise
+ */
+int urldb_search_match_host(const struct host_part *a,
+ const struct host_part *b)
+{
+ int ret;
+
+ assert(a && b);
+
+ /* traverse up tree to root, comparing parts as we go. */
+ for (; a && b; a = a->parent, b = b->parent)
+ if ((ret = strcasecmp(a->part, b->part)) != 0)
+ /* They differ => return the difference here */
+ return ret;
+
+ /* If we get here then either:
+ * a) The path lengths differ
+ * or b) The hosts are identical
+ */
+ if (a && !b)
+ /* len(a) > len(b) */
+ return 1;
+ else if (!a && b)
+ /* len(a) < len(b) */
+ return -1;
+
+ /* identical */
+ return 0;
+}
+
+/**
+ * Compare host_part with a string
+ *
+ * \param a
+ * \param b
+ * \return 0 if match, non-zero, otherwise
+ */
+int urldb_search_match_string(const struct host_part *a,
+ const char *b)
+{
+ const char *end, *dot;
+ int plen, ret;
+
+ assert(a && b);
+
+ if (*b >= '0' && *b <= '9') {
+ /* IP address */
+ return strcasecmp(a->part, b);
+ }
+
+ end = b + strlen(b);
+
+ while (b < end && a) {
+ dot = strchr(b, '.');
+ if (!dot) {
+ /* last segment */
+ dot = end;
+ }
+
+ /* Compare strings (length limited) */
+ if ((ret = strncasecmp(a->part, b, dot - b)) != 0)
+ /* didn't match => return difference */
+ return ret;
+
+ /* The strings matched, now check that the lengths do, too */
+ plen = strlen(a->part);
+
+ if (plen > dot - b)
+ /* len(a) > len(b) */
+ return 1;
+ else if (plen < dot - b)
+ /* len(a) < len(b) */
+ return -1;
+
+ b = dot + 1;
+ a = a->parent;
+ }
+
+ /* If we get here then either:
+ * a) The path lengths differ
+ * or b) The hosts are identical
+ */
+ if (a && a != &db_root && b >= end)
+ /* len(a) > len(b) */
+ return 1;
+ else if (!a && b < end)
+ /* len(a) < len(b) */
+ return -1;
+
+ /* Identical */
+ return 0;
+}
+
+/**
+ * Compare host_part with prefix
+ *
+ * \param a
+ * \param b
+ * \return 0 if match, non-zero, otherwise
+ */
+int urldb_search_match_prefix(const struct host_part *a,
+ const char *b)
+{
+ const char *end, *dot;
+ int plen, ret;
+
+ assert(a && b);
+
+ if (*b >= '0' && *b <= '9') {
+ /* IP address */
+ return strncasecmp(a->part, b, strlen(b));
+ }
+
+ end = b + strlen(b);
+
+ while (b < end && a) {
+ dot = strchr(b, '.');
+ if (!dot) {
+ /* last segment */
+ dot = end;
+ }
+
+ /* Compare strings (length limited) */
+ if ((ret = strncasecmp(a->part, b, dot - b)) != 0)
+ /* didn't match => return difference */
+ return ret;
+
+ /* The strings matched */
+ if (dot < end) {
+ /* Consider segment lengths only in the case
+ * where the prefix contains segments */
+ plen = strlen(a->part);
+ if (plen > dot - b)
+ /* len(a) > len(b) */
+ return 1;
+ else if (plen < dot - b)
+ /* len(a) < len(b) */
+ return -1;
+ }
+
+ b = dot + 1;
+ a = a->parent;
+ }
+
+ /* If we get here then either:
+ * a) The path lengths differ
+ * or b) The hosts are identical
+ */
+ if (a && a != &db_root && b >= end)
+ /* len(a) > len(b) => prefix matches */
+ return 0;
+ else if (!a && b < end)
+ /* len(a) < len(b) => prefix does not match */
+ return -1;
+
+ /* Identical */
+ return 0;
+}
+
+/**
+ * Rotate a subtree right
+ *
+ * \param root Root of subtree to rotate
+ * \return new root of subtree
+ */
+struct search_node *urldb_search_skew(struct search_node *root)
+{
+ struct search_node *temp;
+
+ assert(root);
+
+ if (root->left->level == root->level) {
+ temp = root->left;
+ root->left = temp->right;
+ temp->right = root;
+ root = temp;
+ }
+
+ return root;
+}
+
+/**
+ * Rotate a node left, increasing the parent's level
+ *
+ * \param root Root of subtree to rotate
+ * \return New root of subtree
+ */
+struct search_node *urldb_search_split(struct search_node *root)
+{
+ struct search_node *temp;
+
+ assert(root);
+
+ if (root->right->right->level == root->level) {
+ temp = root->right;
+ root->right = temp->left;
+ temp->left = root;
+ root = temp;
+
+ root->level++;
+ }
+
+ return root;
+}
+
+#ifdef TEST
+int main(void)
+{
+ struct host_part *h;
+ struct path_data *p;
+
+ h = urldb_add_host("127.0.0.1");
+ if (!h) {
+ LOG(("failed adding host"));
+ return 1;
+ }
+
+ /* Get host entry */
+ h = urldb_add_host("netsurf.strcprstskrzkrk.co.uk");
+ if (!h) {
+ LOG(("failed adding host"));
+ return 1;
+ }
+
+ /* Get path entry */
+ p = urldb_add_path("http", 80, h, "/path/to/resource.htm?a=b", "zz");
+ if (!p) {
+ LOG(("failed adding path"));
+ return 1;
+ }
+
+ p = urldb_add_path("http", 80, h, "/path/to/resource.htm?a=b", "aa");
+ if (!p) {
+ LOG(("failed adding path"));
+ return 1;
+ }
+
+ p = urldb_add_path("http", 80, h, "/path/to/resource.htm?a=b", "yy");
+ if (!p) {
+ LOG(("failed adding path"));
+ return 1;
+ }
+
+ urldb_dump();
+
+ return 0;
+}
+#endif
diff --git a/content/urldb.h b/content/urldb.h
new file mode 100644
index 000000000..9d59271d2
--- /dev/null
+++ b/content/urldb.h
@@ -0,0 +1,65 @@
+/*
+ * This file is part of NetSurf, http://netsurf.sourceforge.net/
+ * Licensed under the GNU General Public License,
+ * http://www.opensource.org/licenses/gpl-license
+ * Copyright 2006 John M Bell <jmb202@ecs.soton.ac.uk>
+ */
+
+/** \file
+ * Unified URL information database (interface)
+ */
+
+#ifndef _NETSURF_CONTENT_URLDB_H_
+#define _NETSURF_CONTENT_URLDB_H_
+
+#include <stdbool.h>
+#include <time.h>
+#include "netsurf/content/content_type.h"
+
+struct url_data {
+ const char *title; /**< Resource title */
+ unsigned int visits; /**< Visit count */
+ time_t last_visit; /**< Last visit time */
+ content_type type; /**< Type of resource */
+};
+
+struct bitmap;
+
+/* Persistence support */
+void urldb_load(const char *filename);
+void urldb_save(const char *filename);
+
+/* URL insertion */
+bool urldb_add_url(const char *url);
+
+/* URL data modification / lookup */
+void urldb_set_url_title(const char *url, const char *title);
+void urldb_set_url_content_type(const char *url, content_type type);
+void urldb_update_url_visit_data(const char *url);
+void urldb_reset_url_visit_data(const char *url);
+const struct url_data *urldb_get_url_data(const char *url);
+
+/* Authentication modification / lookup */
+void urldb_set_auth_details(const char *url, const char *realm,
+ const char *auth);
+const char *urldb_get_auth_details(const char *url);
+
+/* SSL certificate permissions */
+void urldb_set_cert_permissions(const char *url, bool permit);
+bool urldb_get_cert_permissions(const char *url);
+
+/* Thumbnail handling */
+void urldb_set_thumbnail(const char *url, struct bitmap *bitmap);
+const struct bitmap *urldb_get_thumbnail(const char *url);
+
+/* URL completion */
+void urldb_iterate_partial(const char *prefix,
+ bool (*callback)(const char *url));
+
+/* Iteration */
+void urldb_iterate_entries(bool (*callback)(const char *url));
+
+/* Debug */
+void urldb_dump(void);
+
+#endif
diff --git a/debug/netsurfd.c b/debug/netsurfd.c
index 4a7f978bd..e3bca4783 100644
--- a/debug/netsurfd.c
+++ b/debug/netsurfd.c
@@ -13,6 +13,7 @@
#include "netsurf/content/fetch.h"
#include "netsurf/content/content.h"
#include "netsurf/content/fetchcache.h"
+#include "netsurf/content/urldb.h"
#include "netsurf/desktop/gui.h"
#include "netsurf/desktop/options.h"
#include "netsurf/desktop/textinput.h"
@@ -162,7 +163,7 @@ bool plugin_redraw(struct content *c, int x, int y,
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale, unsigned long background_colour) {return true;}
void plugin_open(struct content *c, struct browser_window *bw,
- struct content *page, struct box *box,
+ struct content *page, unsigned int index, struct box *box,
struct object_params *params) {}
void plugin_close(struct content *c) {}
bool plugin_handleable(const char *mime_type) {return false;}
@@ -180,7 +181,8 @@ void tree_draw_line(int x, int y, int width, int height) {}
void tree_draw_node_element(struct tree *tree, struct node_element *element) {}
void tree_draw_node_expansion(struct tree *tree, struct node *node) {}
void tree_recalculate_node_element(struct node_element *element) {}
-void tree_update_URL_node(struct node *node, struct url_content *data) {}
+void tree_update_URL_node(struct node *node, const char *url,
+ const struct url_data *data) {}
void tree_resized(struct tree *tree) {}
void tree_set_node_sprite_folder(struct node *node) {}
diff --git a/depend b/depend
index 9acade837..6fc4e3531 100644
--- a/depend
+++ b/depend
@@ -1,89 +1,100 @@
-arm-riscos-aof/content.o arm-ncos-aof/content.o x86_64-linux-gnu-debug/content.o x86_64-linux-gnu-gtk/content.o : content/content.c content/content.h content/content_type.h content/fetch.h content/fetchcache.h css/css.h css/css_enum.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/talloc.h utils/utils.h
-arm-riscos-aof/fetch.o arm-ncos-aof/fetch.o x86_64-linux-gnu-debug/fetch.o x86_64-linux-gnu-gtk/fetch.o : content/fetch.c content/content.h content/content_type.h content/fetch.h css/css.h css/css_enum.h desktop/401login.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/form.h render/html.h riscos/draw.h riscos/gui.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/url.h utils/utils.h
-arm-riscos-aof/fetchcache.o arm-ncos-aof/fetchcache.o x86_64-linux-gnu-debug/fetchcache.o x86_64-linux-gnu-gtk/fetchcache.o : content/fetchcache.c content/content.h content/content_type.h content/fetch.h content/fetchcache.h content/url_store.h css/css.h css/css_enum.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/url.h utils/utils.h
-arm-riscos-aof/url_store.o arm-ncos-aof/url_store.o x86_64-linux-gnu-debug/url_store.o x86_64-linux-gnu-gtk/url_store.o : content/url_store.c content/url_store.h image/bitmap.h riscos/bitmap.h utils/log.h utils/url.h
-arm-riscos-aof/css.o arm-ncos-aof/css.o x86_64-linux-gnu-debug/css.o x86_64-linux-gnu-gtk/css.o : css/css.c content/content.h content/content_type.h content/fetch.h content/fetchcache.h css/css.h css/css_enum.h css/parser.h desktop/browser.h desktop/gui.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/talloc.h utils/url.h utils/utils.h
-arm-riscos-aof/css_enum.o arm-ncos-aof/css_enum.o x86_64-linux-gnu-debug/css_enum.o x86_64-linux-gnu-gtk/css_enum.o : css/css_enum.c css/css_enum.h
-arm-riscos-aof/parser.o arm-ncos-aof/parser.o x86_64-linux-gnu-debug/parser.o x86_64-linux-gnu-gtk/parser.o : css/parser.c css/css.h css/css_enum.h utils/utils.h
-arm-riscos-aof/ruleset.o arm-ncos-aof/ruleset.o x86_64-linux-gnu-debug/ruleset.o x86_64-linux-gnu-gtk/ruleset.o : css/ruleset.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/url.h utils/utils.h
-arm-riscos-aof/scanner.o arm-ncos-aof/scanner.o x86_64-linux-gnu-debug/scanner.o x86_64-linux-gnu-gtk/scanner.o : css/scanner.c css/css.h css/css_enum.h css/parser.h
-arm-riscos-aof/debug_bitmap.o arm-ncos-aof/debug_bitmap.o x86_64-linux-gnu-debug/debug_bitmap.o x86_64-linux-gnu-gtk/debug_bitmap.o : debug/debug_bitmap.c image/bitmap.h
-arm-riscos-aof/filetyped.o arm-ncos-aof/filetyped.o x86_64-linux-gnu-debug/filetyped.o x86_64-linux-gnu-gtk/filetyped.o : debug/filetyped.c content/fetch.h utils/config.h utils/log.h utils/utils.h
-arm-riscos-aof/fontd.o arm-ncos-aof/fontd.o x86_64-linux-gnu-debug/fontd.o x86_64-linux-gnu-gtk/fontd.o : debug/fontd.c css/css.h css/css_enum.h render/font.h
-arm-riscos-aof/netsurfd.o arm-ncos-aof/netsurfd.o x86_64-linux-gnu-debug/netsurfd.o x86_64-linux-gnu-gtk/netsurfd.o : debug/netsurfd.c content/content.h content/content_type.h content/fetch.h content/fetchcache.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/html.h riscos/draw.h riscos/plugin.h riscos/save_complete.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/url.h utils/utils.h
-arm-riscos-aof/browser.o arm-ncos-aof/browser.o x86_64-linux-gnu-debug/browser.o x86_64-linux-gnu-gtk/browser.o : desktop/browser.c content/content.h content/content_type.h content/fetch.h content/fetchcache.h content/url_store.h css/css.h css/css_enum.h desktop/401login.h desktop/browser.h desktop/gui.h desktop/options.h desktop/selection.h desktop/textinput.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/form.h render/html.h render/imagemap.h render/layout.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/talloc.h utils/url.h utils/utf8.h utils/utils.h
-arm-riscos-aof/loginlist.o arm-ncos-aof/loginlist.o x86_64-linux-gnu-debug/loginlist.o x86_64-linux-gnu-gtk/loginlist.o : desktop/loginlist.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/401login.h desktop/browser.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/url.h utils/utils.h
-arm-riscos-aof/netsurf.o arm-ncos-aof/netsurf.o x86_64-linux-gnu-debug/netsurf.o x86_64-linux-gnu-gtk/netsurf.o : desktop/netsurf.c content/content.h content/content_type.h content/fetch.h content/fetchcache.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/buffer.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/talloc.h utils/url.h utils/utf8.h utils/utils.h
-arm-riscos-aof/options.o arm-ncos-aof/options.o x86_64-linux-gnu-debug/options.o x86_64-linux-gnu-gtk/options.o : desktop/options.c css/css.h css/css_enum.h desktop/options.h desktop/tree.h riscos/options.h riscos/tinct.h utils/log.h utils/messages.h utils/utils.h
-arm-riscos-aof/save_text.o arm-ncos-aof/save_text.o x86_64-linux-gnu-debug/save_text.o x86_64-linux-gnu-gtk/save_text.o : desktop/save_text.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/save_text.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/utils.h
-arm-riscos-aof/selection.o arm-ncos-aof/selection.o x86_64-linux-gnu-debug/selection.o x86_64-linux-gnu-gtk/selection.o : desktop/selection.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/plotters.h desktop/selection.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/font.h render/html.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/utils.h
-arm-riscos-aof/textinput.o arm-ncos-aof/textinput.o x86_64-linux-gnu-debug/textinput.o x86_64-linux-gnu-gtk/textinput.o : desktop/textinput.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/selection.h desktop/textinput.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/font.h render/form.h render/html.h render/layout.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/talloc.h utils/utf8.h utils/utils.h
-arm-riscos-aof/tree.o arm-ncos-aof/tree.o x86_64-linux-gnu-debug/tree.o x86_64-linux-gnu-gtk/tree.o : desktop/tree.c desktop/options.h desktop/tree.h utils/log.h utils/utils.h
-arm-riscos-aof/version.o arm-ncos-aof/version.o x86_64-linux-gnu-debug/version.o x86_64-linux-gnu-gtk/version.o : desktop/version.c
-arm-riscos-aof/font_pango.o arm-ncos-aof/font_pango.o x86_64-linux-gnu-debug/font_pango.o x86_64-linux-gnu-gtk/font_pango.o : gtk/font_pango.c css/css.h css/css_enum.h render/font.h utils/log.h utils/utils.h
-arm-riscos-aof/gtk_bitmap.o arm-ncos-aof/gtk_bitmap.o x86_64-linux-gnu-debug/gtk_bitmap.o x86_64-linux-gnu-gtk/gtk_bitmap.o : gtk/gtk_bitmap.c content/content.h content/content_type.h css/css.h css/css_enum.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h
-arm-riscos-aof/gtk_gui.o arm-ncos-aof/gtk_gui.o x86_64-linux-gnu-debug/gtk_gui.o x86_64-linux-gnu-gtk/gtk_gui.o : gtk/gtk_gui.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/401login.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/form.h render/html.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/messages.h utils/utf8.h utils/utils.h
-arm-riscos-aof/gtk_plotters.o arm-ncos-aof/gtk_plotters.o x86_64-linux-gnu-debug/gtk_plotters.o x86_64-linux-gnu-gtk/gtk_plotters.o : gtk/gtk_plotters.c css/css.h css/css_enum.h desktop/plotters.h render/font.h utils/log.h
-arm-riscos-aof/gtk_treeview.o arm-ncos-aof/gtk_treeview.o x86_64-linux-gnu-debug/gtk_treeview.o x86_64-linux-gnu-gtk/gtk_treeview.o : gtk/gtk_treeview.c desktop/tree.h
-arm-riscos-aof/gtk_window.o arm-ncos-aof/gtk_window.o x86_64-linux-gnu-debug/gtk_window.o x86_64-linux-gnu-gtk/gtk_window.o : gtk/gtk_window.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/plotters.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/font.h render/form.h render/html.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/messages.h utils/utils.h
-arm-riscos-aof/gif.o arm-ncos-aof/gif.o x86_64-linux-gnu-debug/gif.o x86_64-linux-gnu-gtk/gif.o : image/gif.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/options.h desktop/plotters.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/utils.h
-arm-riscos-aof/gifread.o arm-ncos-aof/gifread.o x86_64-linux-gnu-debug/gifread.o x86_64-linux-gnu-gtk/gifread.o : image/gifread.c image/bitmap.h utils/log.h
-arm-riscos-aof/jpeg.o arm-ncos-aof/jpeg.o x86_64-linux-gnu-debug/jpeg.o x86_64-linux-gnu-gtk/jpeg.o : image/jpeg.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/plotters.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/utils.h
-arm-riscos-aof/mng.o arm-ncos-aof/mng.o x86_64-linux-gnu-debug/mng.o x86_64-linux-gnu-gtk/mng.o : image/mng.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/options.h desktop/plotters.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/utils.h
-arm-riscos-aof/box.o arm-ncos-aof/box.o x86_64-linux-gnu-debug/box.o x86_64-linux-gnu-gtk/box.o : render/box.c content/content.h content/content_type.h css/css.h css/css_enum.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/form.h render/html.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/talloc.h
-arm-riscos-aof/box_construct.o arm-ncos-aof/box_construct.o x86_64-linux-gnu-debug/box_construct.o x86_64-linux-gnu-gtk/box_construct.o : render/box_construct.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/form.h render/html.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/talloc.h utils/url.h utils/utils.h
-arm-riscos-aof/box_normalise.o arm-ncos-aof/box_normalise.o x86_64-linux-gnu-debug/box_normalise.o x86_64-linux-gnu-gtk/box_normalise.o : render/box_normalise.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/html.h render/table.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h
-arm-riscos-aof/form.o arm-ncos-aof/form.o x86_64-linux-gnu-debug/form.o x86_64-linux-gnu-gtk/form.o : render/form.c render/box.h render/form.h utils/config.h utils/log.h utils/url.h utils/utf8.h utils/utils.h
-arm-riscos-aof/html.o arm-ncos-aof/html.o x86_64-linux-gnu-debug/html.o x86_64-linux-gnu-gtk/html.o : render/html.c content/content.h content/content_type.h content/fetch.h content/fetchcache.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/font.h render/html.h render/imagemap.h render/layout.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/talloc.h utils/url.h utils/utils.h
-arm-riscos-aof/html_redraw.o arm-ncos-aof/html_redraw.o x86_64-linux-gnu-debug/html_redraw.o x86_64-linux-gnu-gtk/html_redraw.o : render/html_redraw.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/plotters.h desktop/selection.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/font.h render/form.h render/html.h render/layout.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/utils.h
-arm-riscos-aof/imagemap.o arm-ncos-aof/imagemap.o x86_64-linux-gnu-debug/imagemap.o x86_64-linux-gnu-gtk/imagemap.o : render/imagemap.c content/content.h content/content_type.h css/css.h css/css_enum.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/html.h render/imagemap.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/utils.h
-arm-riscos-aof/layout.o arm-ncos-aof/layout.o x86_64-linux-gnu-debug/layout.o x86_64-linux-gnu-gtk/layout.o : render/layout.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/font.h render/html.h render/layout.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/talloc.h utils/utils.h
-arm-riscos-aof/list.o arm-ncos-aof/list.o x86_64-linux-gnu-debug/list.o x86_64-linux-gnu-gtk/list.o : render/list.c css/css.h css/css_enum.h render/list.h utils/log.h
-arm-riscos-aof/table.o arm-ncos-aof/table.o x86_64-linux-gnu-debug/table.o x86_64-linux-gnu-gtk/table.o : render/table.c css/css.h css/css_enum.h render/box.h render/table.h utils/log.h utils/talloc.h
-arm-riscos-aof/textplain.o arm-ncos-aof/textplain.o x86_64-linux-gnu-debug/textplain.o x86_64-linux-gnu-gtk/textplain.o : render/textplain.c content/content.h content/content_type.h css/css.h css/css_enum.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/messages.h
-arm-riscos-aof/401login.o arm-ncos-aof/401login.o x86_64-linux-gnu-debug/401login.o x86_64-linux-gnu-gtk/401login.o : riscos/401login.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/401login.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/gui.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/url.h utils/utils.h
-arm-riscos-aof/bitmap.o arm-ncos-aof/bitmap.o x86_64-linux-gnu-debug/bitmap.o x86_64-linux-gnu-gtk/bitmap.o : riscos/bitmap.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/bitmap.h riscos/draw.h riscos/filename.h riscos/image.h riscos/options.h riscos/plugin.h riscos/sprite.h riscos/tinct.h utils/config.h utils/log.h utils/utils.h
-arm-riscos-aof/buffer.o arm-ncos-aof/buffer.o x86_64-linux-gnu-debug/buffer.o x86_64-linux-gnu-gtk/buffer.o : riscos/buffer.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/buffer.h riscos/draw.h riscos/gui.h riscos/options.h riscos/plugin.h riscos/sprite.h riscos/tinct.h riscos/wimp.h utils/config.h utils/log.h
-arm-riscos-aof/debugwin.o arm-ncos-aof/debugwin.o x86_64-linux-gnu-debug/debugwin.o x86_64-linux-gnu-gtk/debugwin.o : riscos/debugwin.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/gui.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/utils.h
-arm-riscos-aof/dialog.o arm-ncos-aof/dialog.o x86_64-linux-gnu-debug/dialog.o x86_64-linux-gnu-gtk/dialog.o : riscos/dialog.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/font.h render/html.h riscos/draw.h riscos/gui.h riscos/menus.h riscos/options.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/tinct.h riscos/wimp.h utils/config.h utils/log.h utils/messages.h utils/url.h utils/utils.h
-arm-riscos-aof/download.o arm-ncos-aof/download.o x86_64-linux-gnu-debug/download.o x86_64-linux-gnu-gtk/download.o : riscos/download.c content/content.h content/content_type.h content/fetch.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/gui.h riscos/options.h riscos/plugin.h riscos/query.h riscos/sprite.h riscos/tinct.h riscos/wimp.h utils/config.h utils/log.h utils/messages.h utils/url.h utils/utf8.h utils/utils.h
-arm-riscos-aof/draw.o arm-ncos-aof/draw.o x86_64-linux-gnu-debug/draw.o x86_64-linux-gnu-gtk/draw.o : riscos/draw.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/gui.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/utils.h
-arm-riscos-aof/filename.o arm-ncos-aof/filename.o x86_64-linux-gnu-debug/filename.o x86_64-linux-gnu-gtk/filename.o : riscos/filename.c riscos/filename.h utils/log.h
-arm-riscos-aof/filetype.o arm-ncos-aof/filetype.o x86_64-linux-gnu-debug/filetype.o x86_64-linux-gnu-gtk/filetype.o : riscos/filetype.c content/content.h content/content_type.h content/fetch.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/gui.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/utils.h
-arm-riscos-aof/font.o arm-ncos-aof/font.o x86_64-linux-gnu-debug/font.o x86_64-linux-gnu-gtk/font.o : riscos/font.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/font.h render/html.h riscos/draw.h riscos/gui.h riscos/options.h riscos/plugin.h riscos/sprite.h riscos/tinct.h utils/config.h utils/log.h utils/messages.h utils/utils.h
-arm-riscos-aof/global_history.o arm-ncos-aof/global_history.o x86_64-linux-gnu-debug/global_history.o x86_64-linux-gnu-gtk/global_history.o : riscos/global_history.c content/content.h content/content_type.h content/url_store.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/global_history.h riscos/gui.h riscos/menus.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/treeview.h utils/config.h utils/log.h utils/messages.h utils/url.h utils/utils.h
-arm-riscos-aof/gui.o arm-ncos-aof/gui.o x86_64-linux-gnu-debug/gui.o x86_64-linux-gnu-gtk/gui.o : riscos/gui.c content/content.h content/content_type.h content/url_store.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/font.h render/html.h riscos/bitmap.h riscos/buffer.h riscos/draw.h riscos/filename.h riscos/global_history.h riscos/gui.h riscos/help.h riscos/menus.h riscos/options.h riscos/plugin.h riscos/print.h riscos/query.h riscos/save_complete.h riscos/sprite.h riscos/theme.h riscos/tinct.h riscos/treeview.h riscos/uri.h riscos/url_complete.h riscos/url_protocol.h riscos/wimp.h utils/config.h utils/log.h utils/messages.h utils/utils.h
-arm-riscos-aof/help.o arm-ncos-aof/help.o x86_64-linux-gnu-debug/help.o x86_64-linux-gnu-gtk/help.o : riscos/help.c content/content.h content/content_type.h content/url_store.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/global_history.h riscos/gui.h riscos/help.h riscos/menus.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/wimp.h utils/config.h utils/log.h utils/messages.h utils/utf8.h utils/utils.h
-arm-riscos-aof/history.o arm-ncos-aof/history.o x86_64-linux-gnu-debug/history.o x86_64-linux-gnu-gtk/history.o : riscos/history.c content/content.h content/content_type.h content/url_store.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/bitmap.h riscos/draw.h riscos/gui.h riscos/image.h riscos/options.h riscos/plugin.h riscos/sprite.h riscos/thumbnail.h riscos/tinct.h riscos/wimp.h utils/config.h utils/log.h utils/url.h utils/utils.h
-arm-riscos-aof/hotlist.o arm-ncos-aof/hotlist.o x86_64-linux-gnu-debug/hotlist.o x86_64-linux-gnu-gtk/hotlist.o : riscos/hotlist.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/gui.h riscos/menus.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/tinct.h riscos/treeview.h riscos/wimp.h utils/config.h utils/log.h utils/messages.h utils/url.h utils/utils.h
-arm-riscos-aof/image.o arm-ncos-aof/image.o x86_64-linux-gnu-debug/image.o x86_64-linux-gnu-gtk/image.o : riscos/image.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/gui.h riscos/image.h riscos/options.h riscos/plugin.h riscos/sprite.h riscos/tinct.h utils/config.h utils/log.h utils/utils.h
-arm-riscos-aof/menus.o arm-ncos-aof/menus.o x86_64-linux-gnu-debug/menus.o x86_64-linux-gnu-gtk/menus.o : riscos/menus.c content/content.h content/content_type.h content/url_store.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/form.h render/html.h riscos/draw.h riscos/global_history.h riscos/gui.h riscos/help.h riscos/menus.h riscos/options.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/tinct.h riscos/treeview.h riscos/wimp.h utils/config.h utils/log.h utils/messages.h utils/url.h utils/utf8.h utils/utils.h
-arm-riscos-aof/mouseactions.o arm-ncos-aof/mouseactions.o x86_64-linux-gnu-debug/mouseactions.o x86_64-linux-gnu-gtk/mouseactions.o : riscos/mouseactions.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/gui.h riscos/menus.h riscos/options.h riscos/plugin.h riscos/sprite.h riscos/tinct.h utils/config.h utils/log.h
-arm-riscos-aof/plotters.o arm-ncos-aof/plotters.o x86_64-linux-gnu-debug/plotters.o x86_64-linux-gnu-gtk/plotters.o : riscos/plotters.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/plotters.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/font.h render/html.h riscos/bitmap.h riscos/draw.h riscos/gui.h riscos/image.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h
-arm-riscos-aof/plugin.o arm-ncos-aof/plugin.o x86_64-linux-gnu-debug/plugin.o x86_64-linux-gnu-gtk/plugin.o : riscos/plugin.c content/content.h content/content_type.h content/fetch.h content/fetchcache.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/html.h riscos/draw.h riscos/gui.h riscos/options.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/tinct.h utils/config.h utils/log.h utils/messages.h utils/url.h utils/utils.h
-arm-riscos-aof/print.o arm-ncos-aof/print.o x86_64-linux-gnu-debug/print.o x86_64-linux-gnu-gtk/print.o : riscos/print.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/plotters.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/font.h render/html.h render/layout.h riscos/draw.h riscos/gui.h riscos/menus.h riscos/plugin.h riscos/print.h riscos/sprite.h riscos/wimp.h utils/config.h utils/log.h utils/messages.h utils/utils.h
-arm-riscos-aof/query.o arm-ncos-aof/query.o x86_64-linux-gnu-debug/query.o x86_64-linux-gnu-gtk/query.o : riscos/query.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/gui.h riscos/plugin.h riscos/query.h riscos/sprite.h riscos/wimp.h utils/config.h utils/log.h utils/messages.h utils/utils.h
-arm-riscos-aof/save.o arm-ncos-aof/save.o x86_64-linux-gnu-debug/save.o x86_64-linux-gnu-gtk/save.o : riscos/save.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/save_text.h desktop/selection.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/html.h riscos/draw.h riscos/gui.h riscos/menus.h riscos/options.h riscos/plugin.h riscos/save_complete.h riscos/save_draw.h riscos/sprite.h riscos/thumbnail.h riscos/tinct.h riscos/wimp.h utils/config.h utils/log.h utils/messages.h utils/url.h utils/utf8.h utils/utils.h
-arm-riscos-aof/save_complete.o arm-ncos-aof/save_complete.o x86_64-linux-gnu-debug/save_complete.o x86_64-linux-gnu-gtk/save_complete.o : riscos/save_complete.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/html.h riscos/draw.h riscos/gui.h riscos/plugin.h riscos/save_complete.h riscos/sprite.h utils/config.h utils/log.h utils/url.h utils/utils.h
-arm-riscos-aof/save_draw.o arm-ncos-aof/save_draw.o x86_64-linux-gnu-debug/save_draw.o x86_64-linux-gnu-gtk/save_draw.o : riscos/save_draw.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/plotters.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/font.h render/form.h render/html.h render/layout.h riscos/bitmap.h riscos/draw.h riscos/plugin.h riscos/save_draw.h riscos/sprite.h utils/config.h utils/log.h utils/utils.h
-arm-riscos-aof/schedule.o arm-ncos-aof/schedule.o x86_64-linux-gnu-debug/schedule.o x86_64-linux-gnu-gtk/schedule.o : riscos/schedule.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/gui.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h
-arm-riscos-aof/search.o arm-ncos-aof/search.o x86_64-linux-gnu-debug/search.o x86_64-linux-gnu-gtk/search.o : riscos/search.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/selection.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/html.h riscos/draw.h riscos/gui.h riscos/menus.h riscos/plugin.h riscos/sprite.h riscos/wimp.h utils/config.h utils/log.h utils/messages.h utils/utils.h
-arm-riscos-aof/sprite.o arm-ncos-aof/sprite.o x86_64-linux-gnu-debug/sprite.o x86_64-linux-gnu-gtk/sprite.o : riscos/sprite.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/gui.h riscos/image.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/utils.h
-arm-riscos-aof/textselection.o arm-ncos-aof/textselection.o x86_64-linux-gnu-debug/textselection.o x86_64-linux-gnu-gtk/textselection.o : riscos/textselection.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/selection.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/html.h riscos/draw.h riscos/gui.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/utf8.h utils/utils.h
-arm-riscos-aof/theme.o arm-ncos-aof/theme.o x86_64-linux-gnu-debug/theme.o x86_64-linux-gnu-gtk/theme.o : riscos/theme.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/gui.h riscos/menus.h riscos/options.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/tinct.h riscos/wimp.h utils/config.h utils/log.h utils/utils.h
-arm-riscos-aof/theme_install.o arm-ncos-aof/theme_install.o x86_64-linux-gnu-debug/theme_install.o x86_64-linux-gnu-gtk/theme_install.o : riscos/theme_install.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/gui.h riscos/options.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/tinct.h riscos/wimp.h utils/config.h utils/log.h utils/messages.h utils/url.h utils/utils.h
-arm-riscos-aof/thumbnail.o arm-ncos-aof/thumbnail.o x86_64-linux-gnu-debug/thumbnail.o x86_64-linux-gnu-gtk/thumbnail.o : riscos/thumbnail.c content/content.h content/content_type.h content/url_store.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/plotters.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/font.h render/html.h riscos/bitmap.h riscos/draw.h riscos/gui.h riscos/options.h riscos/plugin.h riscos/sprite.h riscos/thumbnail.h riscos/tinct.h utils/config.h utils/log.h
-arm-riscos-aof/treeview.o arm-ncos-aof/treeview.o x86_64-linux-gnu-debug/treeview.o x86_64-linux-gnu-gtk/treeview.o : riscos/treeview.c content/content.h content/content_type.h content/url_store.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/bitmap.h riscos/draw.h riscos/gui.h riscos/image.h riscos/menus.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/tinct.h riscos/treeview.h riscos/wimp.h utils/config.h utils/log.h utils/messages.h utils/utils.h
-arm-riscos-aof/ucstables.o arm-ncos-aof/ucstables.o x86_64-linux-gnu-debug/ucstables.o x86_64-linux-gnu-gtk/ucstables.o : riscos/ucstables.c riscos/ucstables.h utils/utf8.h utils/utils.h
-arm-riscos-aof/uri.o arm-ncos-aof/uri.o x86_64-linux-gnu-debug/uri.o x86_64-linux-gnu-gtk/uri.o : riscos/uri.c content/content.h content/content_type.h content/fetch.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/gui.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/url_protocol.h utils/config.h utils/log.h utils/utils.h
-arm-riscos-aof/url_complete.o arm-ncos-aof/url_complete.o x86_64-linux-gnu-debug/url_complete.o x86_64-linux-gnu-gtk/url_complete.o : riscos/url_complete.c content/content.h content/content_type.h content/url_store.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/global_history.h riscos/gui.h riscos/options.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/tinct.h riscos/url_complete.h riscos/wimp.h utils/config.h utils/log.h utils/utils.h
-arm-riscos-aof/url_protocol.o arm-ncos-aof/url_protocol.o x86_64-linux-gnu-debug/url_protocol.o x86_64-linux-gnu-gtk/url_protocol.o : riscos/url_protocol.c content/content.h content/content_type.h content/fetch.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/gui.h riscos/plugin.h riscos/sprite.h riscos/uri.h riscos/url_protocol.h utils/config.h utils/log.h utils/utils.h
-arm-riscos-aof/wimp.o arm-ncos-aof/wimp.o x86_64-linux-gnu-debug/wimp.o x86_64-linux-gnu-gtk/wimp.o : riscos/wimp.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/gui.h riscos/plugin.h riscos/sprite.h riscos/wimp.h utils/config.h utils/log.h utils/utf8.h utils/utils.h
-arm-riscos-aof/window.o arm-ncos-aof/window.o x86_64-linux-gnu-debug/window.o x86_64-linux-gnu-gtk/window.o : riscos/window.c content/content.h content/content_type.h content/url_store.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/plotters.h desktop/textinput.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/form.h render/html.h riscos/buffer.h riscos/draw.h riscos/global_history.h riscos/gui.h riscos/menus.h riscos/options.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/thumbnail.h riscos/tinct.h riscos/treeview.h riscos/ucstables.h riscos/url_complete.h riscos/wimp.h utils/config.h utils/log.h utils/messages.h utils/talloc.h utils/url.h utils/utf8.h utils/utils.h
-arm-riscos-aof/memdebug.o arm-ncos-aof/memdebug.o x86_64-linux-gnu-debug/memdebug.o x86_64-linux-gnu-gtk/memdebug.o : utils/memdebug.c
-arm-riscos-aof/messages.o arm-ncos-aof/messages.o x86_64-linux-gnu-debug/messages.o x86_64-linux-gnu-gtk/messages.o : utils/messages.c utils/log.h utils/messages.h utils/utils.h
-arm-riscos-aof/talloc.o arm-ncos-aof/talloc.o x86_64-linux-gnu-debug/talloc.o x86_64-linux-gnu-gtk/talloc.o : utils/talloc.c
-arm-riscos-aof/translit.o arm-ncos-aof/translit.o x86_64-linux-gnu-debug/translit.o x86_64-linux-gnu-gtk/translit.o : utils/translit.c utils/utils.h
-arm-riscos-aof/url.o arm-ncos-aof/url.o x86_64-linux-gnu-debug/url.o x86_64-linux-gnu-gtk/url.o : utils/url.c utils/log.h utils/url.h utils/utils.h
-arm-riscos-aof/utf8.o arm-ncos-aof/utf8.o x86_64-linux-gnu-debug/utf8.o x86_64-linux-gnu-gtk/utf8.o : utils/utf8.c utils/log.h utils/utf8.h
-arm-riscos-aof/utils.o arm-ncos-aof/utils.o x86_64-linux-gnu-debug/utils.o x86_64-linux-gnu-gtk/utils.o : utils/utils.c utils/config.h utils/log.h utils/messages.h utils/utf8.h utils/utils.h
+arm-riscos-aof/content.o arm-riscos-aof-small/content.o arm-ncos-aof/content.o i486-linux-debug/content.o i486-linux-gtk/content.o : content/content.c content/content.h content/content_type.h content/fetch.h content/fetchcache.h css/css.h css/css_enum.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/talloc.h utils/utils.h
+arm-riscos-aof/fetch.o arm-riscos-aof-small/fetch.o arm-ncos-aof/fetch.o i486-linux-debug/fetch.o i486-linux-gtk/fetch.o : content/fetch.c content/content_type.h content/fetch.h content/urldb.h desktop/options.h desktop/tree.h render/form.h utils/config.h utils/log.h utils/messages.h utils/url.h utils/utils.h
+arm-riscos-aof/fetchcache.o arm-riscos-aof-small/fetchcache.o arm-ncos-aof/fetchcache.o i486-linux-debug/fetchcache.o i486-linux-gtk/fetchcache.o : content/fetchcache.c content/content.h content/content_type.h content/fetch.h content/fetchcache.h css/css.h css/css_enum.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/talloc.h utils/url.h utils/utils.h
+arm-riscos-aof/urldb.o arm-riscos-aof-small/urldb.o arm-ncos-aof/urldb.o i486-linux-debug/urldb.o i486-linux-gtk/urldb.o : content/urldb.c content/content_type.h content/urldb.h desktop/options.h desktop/tree.h image/bitmap.h riscos/bitmap.h utils/config.h utils/log.h utils/url.h utils/utils.h
+arm-riscos-aof/css.o arm-riscos-aof-small/css.o arm-ncos-aof/css.o i486-linux-debug/css.o i486-linux-gtk/css.o : css/css.c content/content.h content/content_type.h content/fetch.h content/fetchcache.h css/css.h css/css_enum.h css/parser.h desktop/browser.h desktop/gui.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/talloc.h utils/url.h utils/utils.h
+arm-riscos-aof/css_enum.o arm-riscos-aof-small/css_enum.o arm-ncos-aof/css_enum.o i486-linux-debug/css_enum.o i486-linux-gtk/css_enum.o : css/css_enum.c css/css_enum.h
+arm-riscos-aof/parser.o arm-riscos-aof-small/parser.o arm-ncos-aof/parser.o i486-linux-debug/parser.o i486-linux-gtk/parser.o : css/parser.c css/css.h css/css_enum.h utils/utils.h
+arm-riscos-aof/ruleset.o arm-riscos-aof-small/ruleset.o arm-ncos-aof/ruleset.o i486-linux-debug/ruleset.o i486-linux-gtk/ruleset.o : css/ruleset.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/url.h utils/utils.h
+arm-riscos-aof/scanner.o arm-riscos-aof-small/scanner.o arm-ncos-aof/scanner.o i486-linux-debug/scanner.o i486-linux-gtk/scanner.o : css/scanner.c css/css.h css/css_enum.h css/parser.h
+arm-riscos-aof/debug_bitmap.o arm-riscos-aof-small/debug_bitmap.o arm-ncos-aof/debug_bitmap.o i486-linux-debug/debug_bitmap.o i486-linux-gtk/debug_bitmap.o : debug/debug_bitmap.c image/bitmap.h
+arm-riscos-aof/filetyped.o arm-riscos-aof-small/filetyped.o arm-ncos-aof/filetyped.o i486-linux-debug/filetyped.o i486-linux-gtk/filetyped.o : debug/filetyped.c content/fetch.h utils/config.h utils/log.h utils/utils.h
+arm-riscos-aof/fontd.o arm-riscos-aof-small/fontd.o arm-ncos-aof/fontd.o i486-linux-debug/fontd.o i486-linux-gtk/fontd.o : debug/fontd.c css/css.h css/css_enum.h render/font.h
+arm-riscos-aof/netsurfd.o arm-riscos-aof-small/netsurfd.o arm-ncos-aof/netsurfd.o i486-linux-debug/netsurfd.o i486-linux-gtk/netsurfd.o : debug/netsurfd.c content/content.h content/content_type.h content/fetch.h content/fetchcache.h content/urldb.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/options.h desktop/textinput.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/box.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/plugin.h riscos/save_complete.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/url.h utils/utils.h
+arm-riscos-aof/browser.o arm-riscos-aof-small/browser.o arm-ncos-aof/browser.o i486-linux-debug/browser.o i486-linux-gtk/browser.o : desktop/browser.c content/content.h content/content_type.h content/fetch.h content/fetchcache.h content/urldb.h css/css.h css/css_enum.h desktop/401login.h desktop/browser.h desktop/gui.h desktop/history_core.h desktop/options.h desktop/selection.h desktop/textinput.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/box.h render/font.h render/form.h render/html.h render/imagemap.h render/layout.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/talloc.h utils/url.h utils/utf8.h utils/utils.h
+arm-riscos-aof/history_core.o arm-riscos-aof-small/history_core.o arm-ncos-aof/history_core.o i486-linux-debug/history_core.o i486-linux-gtk/history_core.o : desktop/history_core.c content/content.h content/content_type.h content/urldb.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/history_core.h desktop/plotters.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/font.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/url.h utils/utils.h
+arm-riscos-aof/netsurf.o arm-riscos-aof-small/netsurf.o arm-ncos-aof/netsurf.o i486-linux-debug/netsurf.o i486-linux-gtk/netsurf.o : desktop/netsurf.c content/content.h content/content_type.h content/fetch.h content/fetchcache.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/buffer.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/url.h utils/utf8.h utils/utils.h
+arm-riscos-aof/options.o arm-riscos-aof-small/options.o arm-ncos-aof/options.o i486-linux-debug/options.o i486-linux-gtk/options.o : desktop/options.c content/content_type.h content/urldb.h css/css.h css/css_enum.h desktop/options.h desktop/tree.h riscos/options.h riscos/tinct.h utils/config.h utils/log.h utils/messages.h utils/utils.h
+arm-riscos-aof/save_text.o arm-riscos-aof-small/save_text.o arm-ncos-aof/save_text.o i486-linux-debug/save_text.o i486-linux-gtk/save_text.o : desktop/save_text.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/save_text.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/utils.h
+arm-riscos-aof/selection.o arm-riscos-aof-small/selection.o arm-ncos-aof/selection.o i486-linux-debug/selection.o i486-linux-gtk/selection.o : desktop/selection.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/plotters.h desktop/selection.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/box.h render/form.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/utf8.h utils/utils.h
+arm-riscos-aof/textinput.o arm-riscos-aof-small/textinput.o arm-ncos-aof/textinput.o i486-linux-debug/textinput.o i486-linux-gtk/textinput.o : desktop/textinput.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/selection.h desktop/textinput.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/box.h render/font.h render/form.h render/html.h render/layout.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/talloc.h utils/utf8.h utils/utils.h
+arm-riscos-aof/tree.o arm-riscos-aof-small/tree.o arm-ncos-aof/tree.o i486-linux-debug/tree.o i486-linux-gtk/tree.o : desktop/tree.c content/content_type.h content/urldb.h desktop/options.h desktop/tree.h utils/config.h utils/log.h utils/utils.h
+arm-riscos-aof/version.o arm-riscos-aof-small/version.o arm-ncos-aof/version.o i486-linux-debug/version.o i486-linux-gtk/version.o : desktop/version.c
+arm-riscos-aof/font_pango.o arm-riscos-aof-small/font_pango.o arm-ncos-aof/font_pango.o i486-linux-debug/font_pango.o i486-linux-gtk/font_pango.o : gtk/font_pango.c css/css.h css/css_enum.h gtk/font_pango.h gtk/gtk_window.h render/font.h utils/log.h utils/utils.h
+arm-riscos-aof/gtk_bitmap.o arm-riscos-aof-small/gtk_bitmap.o arm-ncos-aof/gtk_bitmap.o i486-linux-debug/gtk_bitmap.o i486-linux-gtk/gtk_bitmap.o : gtk/gtk_bitmap.c content/content.h content/content_type.h css/css.h css/css_enum.h gtk/gtk_window.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h
+arm-riscos-aof/gtk_gui.o arm-riscos-aof-small/gtk_gui.o arm-ncos-aof/gtk_gui.o i486-linux-debug/gtk_gui.o i486-linux-gtk/gtk_gui.o : gtk/gtk_gui.c content/content.h content/content_type.h content/fetch.h content/urldb.h css/css.h css/css_enum.h desktop/401login.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h gtk/gtk_gui.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/box.h render/form.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/utf8.h utils/utils.h
+arm-riscos-aof/gtk_plotters.o arm-riscos-aof-small/gtk_plotters.o arm-ncos-aof/gtk_plotters.o i486-linux-debug/gtk_plotters.o i486-linux-gtk/gtk_plotters.o : gtk/gtk_plotters.c css/css.h css/css_enum.h desktop/plotters.h gtk/font_pango.h gtk/gtk_plotters.h gtk/gtk_window.h render/font.h utils/log.h
+arm-riscos-aof/gtk_schedule.o arm-riscos-aof-small/gtk_schedule.o arm-ncos-aof/gtk_schedule.o i486-linux-debug/gtk_schedule.o i486-linux-gtk/gtk_schedule.o : gtk/gtk_schedule.c desktop/browser.h
+arm-riscos-aof/gtk_thumbnail.o arm-riscos-aof-small/gtk_thumbnail.o arm-ncos-aof/gtk_thumbnail.o i486-linux-debug/gtk_thumbnail.o i486-linux-gtk/gtk_thumbnail.o : gtk/gtk_thumbnail.c content/content.h content/content_type.h content/urldb.h css/css.h css/css_enum.h desktop/browser.h desktop/plotters.h gtk/gtk_plotters.h gtk/gtk_window.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/font.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h
+arm-riscos-aof/gtk_treeview.o arm-riscos-aof-small/gtk_treeview.o arm-ncos-aof/gtk_treeview.o i486-linux-debug/gtk_treeview.o i486-linux-gtk/gtk_treeview.o : gtk/gtk_treeview.c desktop/tree.h
+arm-riscos-aof/gtk_window.o arm-riscos-aof-small/gtk_window.o arm-ncos-aof/gtk_window.o i486-linux-debug/gtk_window.o i486-linux-gtk/gtk_window.o : gtk/gtk_window.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/history_core.h desktop/netsurf.h desktop/options.h desktop/plotters.h desktop/tree.h gtk/gtk_gui.h gtk/gtk_plotters.h gtk/gtk_window.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/box.h render/font.h render/form.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/utils.h
+arm-riscos-aof/bmp.o arm-riscos-aof-small/bmp.o arm-ncos-aof/bmp.o i486-linux-debug/bmp.o i486-linux-gtk/bmp.o : image/bmp.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/plotters.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/utils.h
+arm-riscos-aof/bmpread.o arm-riscos-aof-small/bmpread.o arm-ncos-aof/bmpread.o i486-linux-debug/bmpread.o i486-linux-gtk/bmpread.o : image/bmpread.c image/bitmap.h image/bmpread.h utils/log.h
+arm-riscos-aof/gif.o arm-riscos-aof-small/gif.o arm-ncos-aof/gif.o i486-linux-debug/gif.o i486-linux-gtk/gif.o : image/gif.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/options.h desktop/plotters.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/utils.h
+arm-riscos-aof/gifread.o arm-riscos-aof-small/gifread.o arm-ncos-aof/gifread.o i486-linux-debug/gifread.o i486-linux-gtk/gifread.o : image/gifread.c image/bitmap.h utils/log.h
+arm-riscos-aof/ico.o arm-riscos-aof-small/ico.o arm-ncos-aof/ico.o i486-linux-debug/ico.o i486-linux-gtk/ico.o : image/ico.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/plotters.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/utils.h
+arm-riscos-aof/jpeg.o arm-riscos-aof-small/jpeg.o arm-ncos-aof/jpeg.o i486-linux-debug/jpeg.o i486-linux-gtk/jpeg.o : image/jpeg.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/plotters.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/utils.h
+arm-riscos-aof/mng.o arm-riscos-aof-small/mng.o arm-ncos-aof/mng.o i486-linux-debug/mng.o i486-linux-gtk/mng.o : image/mng.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/options.h desktop/plotters.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/utils.h
+arm-riscos-aof/box.o arm-riscos-aof-small/box.o arm-ncos-aof/box.o i486-linux-debug/box.o i486-linux-gtk/box.o : render/box.c content/content.h content/content_type.h css/css.h css/css_enum.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/box.h render/form.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/talloc.h
+arm-riscos-aof/box_construct.o arm-riscos-aof-small/box_construct.o arm-ncos-aof/box_construct.o i486-linux-debug/box_construct.o i486-linux-gtk/box_construct.o : render/box_construct.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/box.h render/form.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/talloc.h utils/url.h utils/utils.h
+arm-riscos-aof/box_normalise.o arm-riscos-aof-small/box_normalise.o arm-ncos-aof/box_normalise.o i486-linux-debug/box_normalise.o i486-linux-gtk/box_normalise.o : render/box_normalise.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/box.h render/html.h render/table.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h
+arm-riscos-aof/form.o arm-riscos-aof-small/form.o arm-ncos-aof/form.o i486-linux-debug/form.o i486-linux-gtk/form.o : render/form.c render/box.h render/form.h utils/config.h utils/log.h utils/url.h utils/utf8.h utils/utils.h
+arm-riscos-aof/html.o arm-riscos-aof-small/html.o arm-ncos-aof/html.o i486-linux-debug/html.o i486-linux-gtk/html.o : render/html.c content/content.h content/content_type.h content/fetch.h content/fetchcache.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/box.h render/font.h render/html.h render/imagemap.h render/layout.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/talloc.h utils/url.h utils/utils.h
+arm-riscos-aof/html_redraw.o arm-riscos-aof-small/html_redraw.o arm-ncos-aof/html_redraw.o i486-linux-debug/html_redraw.o i486-linux-gtk/html_redraw.o : render/html_redraw.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/plotters.h desktop/selection.h desktop/textinput.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/box.h render/font.h render/form.h render/html.h render/layout.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/utils.h
+arm-riscos-aof/imagemap.o arm-riscos-aof-small/imagemap.o arm-ncos-aof/imagemap.o i486-linux-debug/imagemap.o i486-linux-gtk/imagemap.o : render/imagemap.c content/content.h content/content_type.h css/css.h css/css_enum.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/box.h render/html.h render/imagemap.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/utils.h
+arm-riscos-aof/layout.o arm-riscos-aof-small/layout.o arm-ncos-aof/layout.o i486-linux-debug/layout.o i486-linux-gtk/layout.o : render/layout.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/box.h render/font.h render/html.h render/layout.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/talloc.h utils/utils.h
+arm-riscos-aof/list.o arm-riscos-aof-small/list.o arm-ncos-aof/list.o i486-linux-debug/list.o i486-linux-gtk/list.o : render/list.c css/css.h css/css_enum.h render/list.h utils/log.h
+arm-riscos-aof/table.o arm-riscos-aof-small/table.o arm-ncos-aof/table.o i486-linux-debug/table.o i486-linux-gtk/table.o : render/table.c css/css.h css/css_enum.h render/box.h render/table.h utils/log.h utils/talloc.h
+arm-riscos-aof/textplain.o arm-riscos-aof-small/textplain.o arm-ncos-aof/textplain.o i486-linux-debug/textplain.o i486-linux-gtk/textplain.o : render/textplain.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/plotters.h desktop/selection.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/box.h render/font.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/talloc.h utils/utf8.h utils/utils.h
+arm-riscos-aof/401login.o arm-riscos-aof-small/401login.o arm-ncos-aof/401login.o i486-linux-debug/401login.o i486-linux-gtk/401login.o : riscos/401login.c content/content.h content/content_type.h content/urldb.h css/css.h css/css_enum.h desktop/401login.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/dialog.h riscos/draw.h riscos/gui.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/wimp_event.h utils/config.h utils/log.h utils/messages.h utils/url.h utils/utils.h
+arm-riscos-aof/artworks.o arm-riscos-aof-small/artworks.o arm-ncos-aof/artworks.o i486-linux-debug/artworks.o i486-linux-gtk/artworks.o : riscos/artworks.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/gui.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/utils.h
+arm-riscos-aof/assert.o arm-riscos-aof-small/assert.o arm-ncos-aof/assert.o i486-linux-debug/assert.o i486-linux-gtk/assert.o : riscos/assert.c
+arm-riscos-aof/bitmap.o arm-riscos-aof-small/bitmap.o arm-ncos-aof/bitmap.o i486-linux-debug/bitmap.o i486-linux-gtk/bitmap.o : riscos/bitmap.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/bitmap.h riscos/draw.h riscos/filename.h riscos/image.h riscos/options.h riscos/palettes.h riscos/plugin.h riscos/sprite.h riscos/tinct.h utils/config.h utils/log.h utils/utils.h
+arm-riscos-aof/buffer.o arm-riscos-aof-small/buffer.o arm-ncos-aof/buffer.o i486-linux-debug/buffer.o i486-linux-gtk/buffer.o : riscos/buffer.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/buffer.h riscos/draw.h riscos/gui.h riscos/options.h riscos/plugin.h riscos/sprite.h riscos/tinct.h riscos/wimp.h utils/config.h utils/log.h
+arm-riscos-aof/configure.o arm-riscos-aof-small/configure.o arm-ncos-aof/configure.o i486-linux-debug/configure.o i486-linux-gtk/configure.o : riscos/configure.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/configure.h riscos/configure/configure.h riscos/dialog.h riscos/draw.h riscos/gui.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/wimp_event.h utils/config.h utils/log.h utils/messages.h utils/utils.h
+arm-riscos-aof/debugwin.o arm-riscos-aof-small/debugwin.o arm-ncos-aof/debugwin.o i486-linux-debug/debugwin.o i486-linux-gtk/debugwin.o : riscos/debugwin.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/dialog.h riscos/draw.h riscos/gui.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/wimp_event.h utils/config.h utils/log.h utils/utils.h
+arm-riscos-aof/dialog.o arm-riscos-aof-small/dialog.o arm-ncos-aof/dialog.o i486-linux-debug/dialog.o i486-linux-gtk/dialog.o : riscos/dialog.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/font.h render/html.h render/textplain.h riscos/artworks.h riscos/configure.h riscos/dialog.h riscos/draw.h riscos/global_history.h riscos/gui.h riscos/menus.h riscos/options.h riscos/plugin.h riscos/save.h riscos/sprite.h riscos/theme.h riscos/tinct.h riscos/url_complete.h riscos/wimp.h riscos/wimp_event.h utils/config.h utils/log.h utils/messages.h utils/url.h utils/utils.h
+arm-riscos-aof/download.o arm-riscos-aof-small/download.o arm-ncos-aof/download.o i486-linux-debug/download.o i486-linux-gtk/download.o : riscos/download.c content/content.h content/content_type.h content/fetch.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/dialog.h riscos/draw.h riscos/gui.h riscos/options.h riscos/plugin.h riscos/query.h riscos/save.h riscos/sprite.h riscos/theme.h riscos/tinct.h riscos/wimp.h utils/config.h utils/log.h utils/messages.h utils/url.h utils/utf8.h utils/utils.h
+arm-riscos-aof/draw.o arm-riscos-aof-small/draw.o arm-ncos-aof/draw.o i486-linux-debug/draw.o i486-linux-gtk/draw.o : riscos/draw.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/gui.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/utils.h
+arm-riscos-aof/filename.o arm-riscos-aof-small/filename.o arm-ncos-aof/filename.o i486-linux-debug/filename.o i486-linux-gtk/filename.o : riscos/filename.c riscos/filename.h utils/log.h
+arm-riscos-aof/filetype.o arm-riscos-aof-small/filetype.o arm-ncos-aof/filetype.o i486-linux-debug/filetype.o i486-linux-gtk/filetype.o : riscos/filetype.c content/content.h content/content_type.h content/fetch.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/gui.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/utils.h
+arm-riscos-aof/font.o arm-riscos-aof-small/font.o arm-ncos-aof/font.o i486-linux-debug/font.o i486-linux-gtk/font.o : riscos/font.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/font.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/gui.h riscos/options.h riscos/plugin.h riscos/sprite.h riscos/tinct.h utils/config.h utils/log.h utils/messages.h utils/utils.h
+arm-riscos-aof/global_history.o arm-riscos-aof-small/global_history.o arm-ncos-aof/global_history.o i486-linux-debug/global_history.o i486-linux-gtk/global_history.o : riscos/global_history.c content/content.h content/content_type.h content/urldb.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/dialog.h riscos/draw.h riscos/global_history.h riscos/gui.h riscos/menus.h riscos/options.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/tinct.h riscos/treeview.h riscos/wimp.h riscos/wimp_event.h utils/config.h utils/log.h utils/messages.h utils/url.h utils/utils.h
+arm-riscos-aof/gui.o arm-riscos-aof-small/gui.o arm-ncos-aof/gui.o i486-linux-debug/gui.o i486-linux-gtk/gui.o : riscos/gui.c content/content.h content/content_type.h content/urldb.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/box.h render/font.h render/html.h render/textplain.h riscos/artworks.h riscos/bitmap.h riscos/buffer.h riscos/dialog.h riscos/draw.h riscos/filename.h riscos/global_history.h riscos/gui.h riscos/help.h riscos/menus.h riscos/message.h riscos/options.h riscos/plugin.h riscos/print.h riscos/query.h riscos/save.h riscos/save_complete.h riscos/sprite.h riscos/textselection.h riscos/theme.h riscos/tinct.h riscos/treeview.h riscos/uri.h riscos/url_complete.h riscos/url_protocol.h riscos/wimp.h riscos/wimp_event.h utils/config.h utils/log.h utils/messages.h utils/url.h utils/utils.h
+arm-riscos-aof/help.o arm-riscos-aof-small/help.o arm-ncos-aof/help.o i486-linux-debug/help.o i486-linux-gtk/help.o : riscos/help.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/global_history.h riscos/gui.h riscos/help.h riscos/menus.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/wimp.h riscos/wimp_event.h utils/config.h utils/log.h utils/messages.h utils/utf8.h utils/utils.h
+arm-riscos-aof/history.o arm-riscos-aof-small/history.o arm-ncos-aof/history.o i486-linux-debug/history.o i486-linux-gtk/history.o : riscos/history.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/history_core.h desktop/netsurf.h desktop/options.h desktop/plotters.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/dialog.h riscos/draw.h riscos/gui.h riscos/options.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/tinct.h riscos/wimp.h riscos/wimp_event.h utils/config.h utils/log.h utils/url.h utils/utils.h
+arm-riscos-aof/hotlist.o arm-riscos-aof-small/hotlist.o arm-ncos-aof/hotlist.o i486-linux-debug/hotlist.o i486-linux-gtk/hotlist.o : riscos/hotlist.c content/content.h content/content_type.h content/urldb.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/dialog.h riscos/draw.h riscos/gui.h riscos/menus.h riscos/options.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/tinct.h riscos/treeview.h riscos/wimp.h riscos/wimp_event.h utils/config.h utils/log.h utils/messages.h utils/url.h utils/utils.h
+arm-riscos-aof/image.o arm-riscos-aof-small/image.o arm-ncos-aof/image.o i486-linux-debug/image.o i486-linux-gtk/image.o : riscos/image.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/gui.h riscos/image.h riscos/options.h riscos/plugin.h riscos/sprite.h riscos/tinct.h utils/config.h utils/log.h utils/utils.h
+arm-riscos-aof/menus.o arm-riscos-aof-small/menus.o arm-ncos-aof/menus.o i486-linux-debug/menus.o i486-linux-gtk/menus.o : riscos/menus.c content/content.h content/content_type.h content/urldb.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/history_core.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/box.h render/form.h render/html.h render/textplain.h riscos/artworks.h riscos/configure.h riscos/dialog.h riscos/draw.h riscos/global_history.h riscos/gui.h riscos/help.h riscos/menus.h riscos/options.h riscos/plugin.h riscos/save.h riscos/sprite.h riscos/theme.h riscos/tinct.h riscos/treeview.h riscos/wimp.h riscos/wimp_event.h utils/config.h utils/log.h utils/messages.h utils/url.h utils/utf8.h utils/utils.h
+arm-riscos-aof/message.o arm-riscos-aof-small/message.o arm-ncos-aof/message.o i486-linux-debug/message.o i486-linux-gtk/message.o : riscos/message.c riscos/message.h utils/log.h utils/utils.h
+arm-riscos-aof/mouseactions.o arm-riscos-aof-small/mouseactions.o arm-ncos-aof/mouseactions.o i486-linux-debug/mouseactions.o i486-linux-gtk/mouseactions.o : riscos/mouseactions.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/gui.h riscos/menus.h riscos/options.h riscos/plugin.h riscos/sprite.h riscos/tinct.h utils/config.h utils/log.h
+arm-riscos-aof/palettes.o arm-riscos-aof-small/palettes.o arm-ncos-aof/palettes.o i486-linux-debug/palettes.o i486-linux-gtk/palettes.o : riscos/palettes.c riscos/palettes.h
+arm-riscos-aof/plotters.o arm-riscos-aof-small/plotters.o arm-ncos-aof/plotters.o i486-linux-debug/plotters.o i486-linux-gtk/plotters.o : riscos/plotters.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/plotters.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/font.h render/html.h render/textplain.h riscos/artworks.h riscos/bitmap.h riscos/draw.h riscos/gui.h riscos/image.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h
+arm-riscos-aof/plugin.o arm-riscos-aof-small/plugin.o arm-ncos-aof/plugin.o i486-linux-debug/plugin.o i486-linux-gtk/plugin.o : riscos/plugin.c content/content.h content/content_type.h content/fetch.h content/fetchcache.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/box.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/gui.h riscos/options.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/tinct.h utils/config.h utils/log.h utils/messages.h utils/url.h utils/utils.h
+arm-riscos-aof/print.o arm-riscos-aof-small/print.o arm-ncos-aof/print.o i486-linux-debug/print.o i486-linux-gtk/print.o : riscos/print.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/plotters.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/box.h render/font.h render/html.h render/layout.h render/textplain.h riscos/artworks.h riscos/dialog.h riscos/draw.h riscos/gui.h riscos/menus.h riscos/plugin.h riscos/print.h riscos/sprite.h riscos/theme.h riscos/wimp.h riscos/wimp_event.h utils/config.h utils/log.h utils/messages.h utils/utils.h
+arm-riscos-aof/query.o arm-riscos-aof-small/query.o arm-ncos-aof/query.o i486-linux-debug/query.o i486-linux-gtk/query.o : riscos/query.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/dialog.h riscos/draw.h riscos/gui.h riscos/plugin.h riscos/query.h riscos/sprite.h riscos/theme.h riscos/wimp.h utils/config.h utils/log.h utils/messages.h utils/utils.h
+arm-riscos-aof/save.o arm-riscos-aof-small/save.o arm-ncos-aof/save.o i486-linux-debug/save.o i486-linux-gtk/save.o : riscos/save.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/save_text.h desktop/selection.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/box.h render/html.h render/textplain.h riscos/artworks.h riscos/dialog.h riscos/draw.h riscos/gui.h riscos/menus.h riscos/options.h riscos/plugin.h riscos/save.h riscos/save_complete.h riscos/save_draw.h riscos/sprite.h riscos/textselection.h riscos/theme.h riscos/thumbnail.h riscos/tinct.h riscos/wimp.h riscos/wimp_event.h utils/config.h utils/log.h utils/messages.h utils/url.h utils/utf8.h utils/utils.h
+arm-riscos-aof/save_complete.o arm-riscos-aof-small/save_complete.o arm-ncos-aof/save_complete.o i486-linux-debug/save_complete.o i486-linux-gtk/save_complete.o : riscos/save_complete.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/box.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/gui.h riscos/plugin.h riscos/save_complete.h riscos/sprite.h utils/config.h utils/log.h utils/url.h utils/utils.h
+arm-riscos-aof/save_draw.o arm-riscos-aof-small/save_draw.o arm-ncos-aof/save_draw.o i486-linux-debug/save_draw.o i486-linux-gtk/save_draw.o : riscos/save_draw.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/plotters.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/bitmap.h riscos/draw.h riscos/gui.h riscos/plugin.h riscos/save_draw.h riscos/sprite.h utils/config.h utils/log.h utils/utils.h
+arm-riscos-aof/schedule.o arm-riscos-aof-small/schedule.o arm-ncos-aof/schedule.o i486-linux-debug/schedule.o i486-linux-gtk/schedule.o : riscos/schedule.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/gui.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h
+arm-riscos-aof/search.o arm-riscos-aof-small/search.o arm-ncos-aof/search.o i486-linux-debug/search.o i486-linux-gtk/search.o : riscos/search.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/selection.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/box.h render/html.h render/textplain.h riscos/artworks.h riscos/dialog.h riscos/draw.h riscos/gui.h riscos/menus.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/wimp.h riscos/wimp_event.h utils/config.h utils/log.h utils/messages.h utils/utils.h
+arm-riscos-aof/sprite.o arm-riscos-aof-small/sprite.o arm-ncos-aof/sprite.o i486-linux-debug/sprite.o i486-linux-gtk/sprite.o : riscos/sprite.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/gui.h riscos/image.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/utils.h
+arm-riscos-aof/sslcert.o arm-riscos-aof-small/sslcert.o arm-ncos-aof/sslcert.o i486-linux-debug/sslcert.o i486-linux-gtk/sslcert.o : riscos/sslcert.c content/content.h content/content_type.h content/fetch.h content/urldb.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/dialog.h riscos/draw.h riscos/gui.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/wimp_event.h utils/config.h utils/log.h utils/utils.h
+arm-riscos-aof/textselection.o arm-riscos-aof-small/textselection.o arm-ncos-aof/textselection.o i486-linux-debug/textselection.o i486-linux-gtk/textselection.o : riscos/textselection.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/selection.h desktop/textinput.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/box.h render/form.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/gui.h riscos/message.h riscos/plugin.h riscos/save.h riscos/sprite.h riscos/textselection.h utils/config.h utils/log.h utils/utf8.h utils/utils.h
+arm-riscos-aof/theme.o arm-riscos-aof-small/theme.o arm-ncos-aof/theme.o i486-linux-debug/theme.o i486-linux-gtk/theme.o : riscos/theme.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/dialog.h riscos/draw.h riscos/gui.h riscos/menus.h riscos/options.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/tinct.h riscos/treeview.h riscos/wimp.h riscos/wimp_event.h utils/config.h utils/log.h utils/utils.h
+arm-riscos-aof/theme_install.o arm-riscos-aof-small/theme_install.o arm-ncos-aof/theme_install.o i486-linux-debug/theme_install.o i486-linux-gtk/theme_install.o : riscos/theme_install.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/dialog.h riscos/draw.h riscos/gui.h riscos/options.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/tinct.h riscos/wimp.h riscos/wimp_event.h utils/config.h utils/log.h utils/messages.h utils/url.h utils/utils.h
+arm-riscos-aof/thumbnail.o arm-riscos-aof-small/thumbnail.o arm-ncos-aof/thumbnail.o i486-linux-debug/thumbnail.o i486-linux-gtk/thumbnail.o : riscos/thumbnail.c content/content.h content/content_type.h content/urldb.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/plotters.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/font.h render/html.h render/textplain.h riscos/artworks.h riscos/bitmap.h riscos/draw.h riscos/gui.h riscos/options.h riscos/plugin.h riscos/sprite.h riscos/thumbnail.h riscos/tinct.h utils/config.h utils/log.h
+arm-riscos-aof/treeview.o arm-riscos-aof-small/treeview.o arm-ncos-aof/treeview.o i486-linux-debug/treeview.o i486-linux-gtk/treeview.o : riscos/treeview.c content/content.h content/content_type.h content/urldb.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/bitmap.h riscos/dialog.h riscos/draw.h riscos/gui.h riscos/image.h riscos/menus.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/tinct.h riscos/treeview.h riscos/wimp.h riscos/wimp_event.h utils/config.h utils/log.h utils/messages.h utils/utils.h
+arm-riscos-aof/ucstables.o arm-riscos-aof-small/ucstables.o arm-ncos-aof/ucstables.o i486-linux-debug/ucstables.o i486-linux-gtk/ucstables.o : riscos/ucstables.c riscos/ucstables.h utils/log.h utils/utf8.h utils/utils.h
+arm-riscos-aof/uri.o arm-riscos-aof-small/uri.o arm-ncos-aof/uri.o i486-linux-debug/uri.o i486-linux-gtk/uri.o : riscos/uri.c content/content.h content/content_type.h content/fetch.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/gui.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/url_protocol.h utils/config.h utils/log.h utils/utils.h
+arm-riscos-aof/url_complete.o arm-riscos-aof-small/url_complete.o arm-ncos-aof/url_complete.o i486-linux-debug/url_complete.o i486-linux-gtk/url_complete.o : riscos/url_complete.c content/content.h content/content_type.h content/urldb.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/global_history.h riscos/gui.h riscos/options.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/tinct.h riscos/url_complete.h riscos/wimp.h utils/config.h utils/log.h utils/utils.h
+arm-riscos-aof/url_protocol.o arm-riscos-aof-small/url_protocol.o arm-ncos-aof/url_protocol.o i486-linux-debug/url_protocol.o i486-linux-gtk/url_protocol.o : riscos/url_protocol.c content/content.h content/content_type.h content/fetch.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/gui.h riscos/plugin.h riscos/sprite.h riscos/uri.h riscos/url_protocol.h utils/config.h utils/log.h utils/utils.h
+arm-riscos-aof/wimp.o arm-riscos-aof-small/wimp.o arm-ncos-aof/wimp.o i486-linux-debug/wimp.o i486-linux-gtk/wimp.o : riscos/wimp.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/draw.h riscos/gui.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/wimp.h utils/config.h utils/log.h utils/utf8.h utils/utils.h
+arm-riscos-aof/wimp_event.o arm-riscos-aof-small/wimp_event.o arm-ncos-aof/wimp_event.o i486-linux-debug/wimp_event.o i486-linux-gtk/wimp_event.o : riscos/wimp_event.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/html.h render/textplain.h riscos/artworks.h riscos/dialog.h riscos/draw.h riscos/gui.h riscos/menus.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/wimp.h riscos/wimp_event.h utils/config.h utils/log.h utils/utils.h
+arm-riscos-aof/window.o arm-riscos-aof-small/window.o arm-ncos-aof/window.o i486-linux-debug/window.o i486-linux-gtk/window.o : riscos/window.c content/content.h content/content_type.h content/urldb.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/netsurf.h desktop/options.h desktop/plotters.h desktop/textinput.h desktop/tree.h image/bitmap.h image/bmp.h image/bmpread.h image/gif.h image/gifread.h image/ico.h image/jpeg.h image/mng.h render/box.h render/form.h render/html.h render/textplain.h riscos/artworks.h riscos/bitmap.h riscos/buffer.h riscos/dialog.h riscos/draw.h riscos/global_history.h riscos/gui.h riscos/menus.h riscos/options.h riscos/plugin.h riscos/sprite.h riscos/theme.h riscos/thumbnail.h riscos/tinct.h riscos/ucstables.h riscos/url_complete.h riscos/wimp.h utils/config.h utils/log.h utils/messages.h utils/talloc.h utils/url.h utils/utf8.h utils/utils.h
+arm-riscos-aof/memdebug.o arm-riscos-aof-small/memdebug.o arm-ncos-aof/memdebug.o i486-linux-debug/memdebug.o i486-linux-gtk/memdebug.o : utils/memdebug.c
+arm-riscos-aof/messages.o arm-riscos-aof-small/messages.o arm-ncos-aof/messages.o i486-linux-debug/messages.o i486-linux-gtk/messages.o : utils/messages.c utils/log.h utils/messages.h utils/utils.h
+arm-riscos-aof/talloc.o arm-riscos-aof-small/talloc.o arm-ncos-aof/talloc.o i486-linux-debug/talloc.o i486-linux-gtk/talloc.o : utils/talloc.c
+arm-riscos-aof/url.o arm-riscos-aof-small/url.o arm-ncos-aof/url.o i486-linux-debug/url.o i486-linux-gtk/url.o : utils/url.c utils/log.h utils/url.h utils/utils.h
+arm-riscos-aof/utf8.o arm-riscos-aof-small/utf8.o arm-ncos-aof/utf8.o i486-linux-debug/utf8.o i486-linux-gtk/utf8.o : utils/utf8.c utils/log.h utils/utf8.h
+arm-riscos-aof/utils.o arm-riscos-aof-small/utils.o arm-ncos-aof/utils.o i486-linux-debug/utils.o i486-linux-gtk/utils.o : utils/utils.c utils/config.h utils/log.h utils/messages.h utils/utf8.h utils/utils.h
diff --git a/desktop/browser.c b/desktop/browser.c
index da6514e3d..7948ca9fa 100644
--- a/desktop/browser.c
+++ b/desktop/browser.c
@@ -23,7 +23,7 @@
#include "netsurf/utils/config.h"
#include "netsurf/content/fetch.h"
#include "netsurf/content/fetchcache.h"
-#include "netsurf/content/url_store.h"
+#include "netsurf/content/urldb.h"
#include "netsurf/css/css.h"
#ifdef WITH_AUTH
#include "netsurf/desktop/401login.h"
@@ -262,11 +262,9 @@ void browser_window_go_post(struct browser_window *bw, const char *url,
void browser_window_callback(content_msg msg, struct content *c,
intptr_t p1, intptr_t p2, union content_msg_data data)
{
- struct url_content *url_content;
struct browser_window *bw = (struct browser_window *) p1;
char status[40];
char url[256];
- char *title;
switch (msg) {
case CONTENT_MSG_LOADING:
@@ -327,21 +325,14 @@ void browser_window_callback(content_msg msg, struct content *c,
browser_window_set_status(bw, c->status_message);
if (bw->history_add) {
history_add(bw->history, c, bw->frag_id);
- url_content = url_store_find(c->url);
- if (url_content) {
- if (c->title)
- title = strdup(c->title);
- else
- title = strdup(c->url);
- if (title) {
- free(url_content->title);
- url_content->title = title;
- }
- url_content->visits++;
- url_content->last_visit = time(NULL);
- url_content->type = c->type;
- global_history_add(url_content);
- }
+ if (!urldb_add_url(c->url))
+ LOG(("urldb_add_url failed"));
+
+ urldb_set_url_title(c->url,
+ c->title ? c->title : c->url);
+ urldb_update_url_visit_data(c->url);
+ urldb_set_url_content_type(c->url, c->type);
+ global_history_add(c->url);
}
switch (c->type) {
case CONTENT_HTML:
@@ -846,11 +837,11 @@ void browser_window_mouse_action_html(struct browser_window *bw,
* box with scrollbars */
box = c->data.html.layout;
-
+
/* Consider the margins of the html page now */
box_x = box->margin[LEFT];
box_y = box->margin[TOP];
-
+
while ((next_box = box_at_point(box, x, y, &box_x, &box_y, &content)) !=
NULL) {
box = next_box;
@@ -2027,7 +2018,7 @@ struct box *browser_window_pick_text_box(struct browser_window *bw,
int box_x = 0, box_y = 0;
struct content *content;
struct box *next_box;
-
+
/* Consider the margins of the html page now */
box_x = box->margin[LEFT];
box_y = box->margin[TOP];
diff --git a/desktop/browser.h b/desktop/browser.h
index 1d1239cb0..8edc699a6 100644
--- a/desktop/browser.h
+++ b/desktop/browser.h
@@ -16,7 +16,6 @@
#include <stdbool.h>
#include <stddef.h>
#include <time.h>
-#include "netsurf/content/url_store.h"
struct box;
struct content;
@@ -27,6 +26,8 @@ struct gui_window;
struct history;
struct selection;
struct browser_window;
+struct url_data;
+struct bitmap;
typedef void (*browser_caret_callback)(struct browser_window *bw,
@@ -95,7 +96,7 @@ struct browser_window {
/** Current fetch is download */
bool download;
-
+
/** Refresh interval (-1 if undefined) */
int refresh_interval;
};
@@ -154,7 +155,7 @@ void browser_window_redraw_rect(struct browser_window *bw, int x, int y,
void hotlist_visited(struct content *content);
/* In platform specific global_history.c. */
-void global_history_add(struct url_content *data);
+void global_history_add(const char *url);
void global_history_add_recent(const char *url);
char **global_history_get_recent(int *count);
diff --git a/desktop/history_core.c b/desktop/history_core.c
index 67cee27ae..d851423f1 100644
--- a/desktop/history_core.c
+++ b/desktop/history_core.c
@@ -16,7 +16,7 @@
#include <string.h>
#include <time.h>
#include "netsurf/content/content.h"
-#include "netsurf/content/url_store.h"
+#include "netsurf/content/urldb.h"
#include "netsurf/css/css.h"
#include "netsurf/desktop/gui.h"
#include "netsurf/desktop/history_core.h"
@@ -115,7 +115,7 @@ void history_add(struct history *history, struct content *content,
struct history_entry *entry;
char *url;
char *title;
- struct bitmap *bitmap;
+ const struct bitmap *bitmap;
assert(history);
assert(content);
@@ -159,7 +159,7 @@ void history_add(struct history *history, struct content *content,
/* if we have a thumbnail, don't update until the page has finished
* loading */
- bitmap = url_store_get_thumbnail(url);
+ bitmap = urldb_get_thumbnail(url);
if (!bitmap) {
bitmap = bitmap_create(WIDTH, HEIGHT,
BITMAP_NEW | BITMAP_CLEAR_MEMORY |
diff --git a/desktop/options.c b/desktop/options.c
index 448bb78f7..58637f61e 100644
--- a/desktop/options.c
+++ b/desktop/options.c
@@ -21,6 +21,7 @@
#include <string.h>
#include "libxml/HTMLparser.h"
#include "libxml/HTMLtree.h"
+#include "netsurf/content/urldb.h"
#include "netsurf/css/css.h"
#include "netsurf/desktop/options.h"
#include "netsurf/desktop/tree.h"
@@ -92,7 +93,7 @@ char *option_homepage_url = 0;
/** Maximum simultaneous active fetchers */
int option_max_fetchers = 24;
/** Maximum simultaneous active fetchers per host.
- * (<=option_max_fetchers else it makes no sense
+ * (<=option_max_fetchers else it makes no sense
*/
int option_max_fetchers_per_host = 5;
/** Maximum number of inactive fetchers cached.
@@ -413,7 +414,7 @@ void options_load_tree_entry(xmlNode *li, struct node *directory) {
char *title = 0;
struct node *entry;
xmlNode *n;
- struct url_content *data;
+ const struct url_data *data;
for (n = li->children; n; n = n->next) {
/* The li must contain an "a" element */
@@ -430,12 +431,17 @@ void options_load_tree_entry(xmlNode *li, struct node *directory) {
return;
}
- data = url_store_find(url);
+ data = urldb_get_url_data(url);
+ if (!data)
+ /* No entry in database, so add one */
+ urldb_add_url(url);
+
+ data = urldb_get_url_data(url);
if (!data)
return;
if (!data->title)
- data->title = strdup(title);
- entry = tree_create_URL_node(directory, data, title);
+ urldb_set_url_title(url, title);
+ entry = tree_create_URL_node(directory, url, data, title);
xmlFree(url);
xmlFree(title);
}
diff --git a/desktop/tree.c b/desktop/tree.c
index 921ed8042..ae4821e3c 100644
--- a/desktop/tree.c
+++ b/desktop/tree.c
@@ -14,23 +14,25 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "netsurf/content/url_store.h"
+#include "netsurf/content/urldb.h"
#include "netsurf/desktop/tree.h"
#include "netsurf/desktop/options.h"
#include "netsurf/utils/log.h"
#include "netsurf/utils/utils.h"
-static void tree_draw_node(struct tree *tree, struct node *node, int clip_x, int clip_y,
- int clip_width, int clip_height);
-static struct node_element *tree_create_node_element(struct node *parent, node_element_data data);
+static void tree_draw_node(struct tree *tree, struct node *node, int clip_x,
+ int clip_y, int clip_width, int clip_height);
+static struct node_element *tree_create_node_element(struct node *parent,
+ node_element_data data);
static int tree_get_node_width(struct node *node);
static int tree_get_node_height(struct node *node);
-static void tree_handle_selection_area_node(struct tree *tree, struct node *node, int x, int y,
- int width, int height, bool invert);
+static void tree_handle_selection_area_node(struct tree *tree,
+ struct node *node, int x, int y, int width, int height,
+ bool invert);
static void tree_selected_to_processing(struct node *node);
void tree_clear_processing(struct node *node);
-struct node *tree_move_processing_node(struct node *node, struct node *link, bool before,
- bool first);
+struct node *tree_move_processing_node(struct node *node, struct node *link,
+ bool before, bool first);
static int tree_initialising = 0;
@@ -873,55 +875,51 @@ void tree_delete_selected_nodes(struct tree *tree, struct node *node) {
void tree_delete_node(struct tree *tree, struct node *node, bool siblings) {
struct node *next;
struct node *parent;
- struct node_element *element;
- struct url_content *data;
+ struct node_element *e, *f;
assert(node);
- while (node) {
- if (tree->temp_selection == node)
- tree->temp_selection = NULL;
-
- next = node->next;
- if (node->child)
- tree_delete_node(tree, node->child, true);
- node->child = NULL;
- parent = node->parent;
- tree_delink_node(node);
- if (!node->retain_in_memory) {
- for (element = &node->data; element; element = element->next) {
- if (element->text) {
- /* we don't free non-editable titles or URLs */
- if ((node->editable) ||
- ((node->data.data != TREE_ELEMENT_TITLE) &&
- (node->data.data != TREE_ELEMENT_URL)))
- free(element->text);
- else if (node->data.data != TREE_ELEMENT_URL) {
+ if (tree->temp_selection == node)
+ tree->temp_selection = NULL;
+
+ next = node->next;
+ if (node->child)
+ tree_delete_node(tree, node->child, true);
+ node->child = NULL;
+ parent = node->parent;
+ tree_delink_node(node);
+
+ if (!node->retain_in_memory) {
+ for (e = &node->data; e; e = f) {
+ f = e->next;
+
+ if (e->text) {
+ /* we don't free non-editable titles */
+ if (node->editable)
+ free(e->text);
+ else {
+ if (e->data == TREE_ELEMENT_URL) {
/* reset URL characteristics */
- data = url_store_find(element->text);
- if (data) {
- data->last_visit = 0;
- data->visits = 0;
- }
+ urldb_reset_url_visit_data(e->text);
}
+
+ if (e->data != TREE_ELEMENT_TITLE)
+ free(e->text);
}
- if (element->sprite)
- free(element->sprite); /* \todo platform specific bits */
- }
- while (node->data.next) {
- element = node->data.next->next;
- free(node->data.next);
- node->data.next = element;
}
- free(node);
- } else {
- node->deleted = true;
+ if (e->sprite)
+ free(e->sprite); /* \todo platform specific bits */
+
+ if (e != &node->data)
+ free(e);
}
- if (!siblings)
- node = NULL;
- else
- node = next;
+ free(node);
+ } else {
+ node->deleted = true;
}
+ if (siblings)
+ tree_delete_node(tree, next, true);
+
tree_recalculate_node_positions(tree->root);
tree_redraw_area(tree, 0, 0, 16384, 16384); /* \todo correct area */
tree_recalculate_size(tree);
@@ -986,11 +984,13 @@ struct node *tree_create_leaf_node(struct node *parent, const char *title) {
*
*
* \param parent the node to link to
+ * \param url the URL (copied)
* \param data the URL data to use
* \param title the custom title to use
* \return the node created, or NULL for failure
*/
-struct node *tree_create_URL_node(struct node *parent, struct url_content *data,
+struct node *tree_create_URL_node(struct node *parent,
+ const char *url, const struct url_data *data,
const char *title) {
struct node *node;
struct node_element *element;
@@ -998,10 +998,10 @@ struct node *tree_create_URL_node(struct node *parent, struct url_content *data,
assert(data);
if (!title) {
- if (data->title)
- title = strdup(data->title);
- else
- title = strdup(data->url);
+ if (data->title)
+ title = strdup(data->title);
+ else
+ title = strdup(url);
if (!title)
return NULL;
}
@@ -1017,9 +1017,9 @@ struct node *tree_create_URL_node(struct node *parent, struct url_content *data,
tree_create_node_element(node, TREE_ELEMENT_LAST_VISIT);
element = tree_create_node_element(node, TREE_ELEMENT_URL);
if (element)
- element->text = strdup(data->url);
+ element->text = strdup(url);
- tree_update_URL_node(node, NULL);
+ tree_update_URL_node(node, url, NULL);
tree_recalculate_node(node, false);
return node;
@@ -1029,24 +1029,30 @@ struct node *tree_create_URL_node(struct node *parent, struct url_content *data,
/**
* Creates a tree entry for a URL, and links it into the tree.
*
- * All information is used directly from the url_content, and as such cannot be
+ * All information is used directly from the url_data, and as such cannot be
* edited and should never be freed.
*
* \param parent the node to link to
+ * \param url the URL (copied)
* \param data the URL data to use
* \return the node created, or NULL for failure
*/
-struct node *tree_create_URL_node_shared(struct node *parent, struct url_content *data) {
+struct node *tree_create_URL_node_shared(struct node *parent,
+ const char *url, const struct url_data *data) {
struct node *node;
struct node_element *element;
char *title;
assert(data);
+ /* If title isn't set, set it to the URL */
+ if (!data->title)
+ urldb_set_url_title(url, url);
+
if (data->title)
title = data->title;
else
- title = data->url;
+ return NULL;
node = tree_create_leaf_node(parent, title);
if (!node)
return NULL;
@@ -1061,9 +1067,9 @@ struct node *tree_create_URL_node_shared(struct node *parent, struct url_content
tree_create_node_element(node, TREE_ELEMENT_LAST_VISIT);
element = tree_create_node_element(node, TREE_ELEMENT_URL);
if (element)
- element->text = data->url;
+ element->text = strdup(url);
- tree_update_URL_node(node, data);
+ tree_update_URL_node(node, url, data);
tree_recalculate_node(node, false);
return node;
diff --git a/desktop/tree.h b/desktop/tree.h
index b5a73089d..ddfd5f6d3 100644
--- a/desktop/tree.h
+++ b/desktop/tree.h
@@ -13,7 +13,8 @@
#define _NETSURF_DESKTOP_TREE_H_
#include <stdbool.h>
-#include "netsurf/content/url_store.h"
+
+struct url_data;
typedef enum {
TREE_ELEMENT_URL,
@@ -117,9 +118,11 @@ struct node *tree_create_folder_node(struct node *parent, const char *title);
struct node *tree_create_leaf_node(struct node *parent, const char *title);
void tree_set_node_sprite(struct node *node, const char *sprite,
const char *expanded);
-struct node *tree_create_URL_node(struct node *parent, struct url_content *data,
+struct node *tree_create_URL_node(struct node *parent,
+ const char *url, const struct url_data *data,
const char *title);
-struct node *tree_create_URL_node_shared(struct node *parent, struct url_content *data);
+struct node *tree_create_URL_node_shared(struct node *parent,
+ const char *url, const struct url_data *data);
void tree_set_node_expanded(struct node *node, bool expanded);
void tree_set_node_selected(struct tree *tree, struct node *node,
bool selected);
@@ -142,7 +145,8 @@ void tree_draw_line(int x, int y, int width, int height);
void tree_draw_node_element(struct tree *tree, struct node_element *element);
void tree_draw_node_expansion(struct tree *tree, struct node *node);
void tree_recalculate_node_element(struct node_element *element);
-void tree_update_URL_node(struct node *node, struct url_content *data);
+void tree_update_URL_node(struct node *node, const char *url,
+ const struct url_data *data);
void tree_resized(struct tree *tree);
void tree_set_node_sprite_folder(struct node *node);
diff --git a/gtk/gtk_gui.c b/gtk/gtk_gui.c
index b97733d46..7c7a0e420 100644
--- a/gtk/gtk_gui.c
+++ b/gtk/gtk_gui.c
@@ -18,7 +18,7 @@
#include <gtk/gtk.h>
#include "netsurf/content/content.h"
#include "netsurf/content/fetch.h"
-#include "netsurf/content/url_store.h"
+#include "netsurf/content/urldb.h"
#include "netsurf/desktop/401login.h"
#include "netsurf/desktop/browser.h"
#include "netsurf/desktop/gui.h"
@@ -128,23 +128,23 @@ void gui_init(int argc, char** argv)
find_resource(buf, "Default.css", "Default.css");
default_stylesheet_url = path_to_url(buf);
LOG(("Using '%s' as Default CSS URL", default_stylesheet_url));
-
+
find_resource(buf, "AdBlock.css", "AdBlock.css");
adblock_stylesheet_url = path_to_url(buf);
LOG(("Using '%s' as AdBlock CSS URL", adblock_stylesheet_url));
-
+
}
void gui_init2(int argc, char** argv)
{
const char *addr = "http://netsurf.sourceforge.net/";
-
+
if (option_homepage_url != NULL)
addr = option_homepage_url;
if (argc > 1) addr = argv[1];
- browser_window_create(addr, 0, 0);
+ browser_window_create(addr, 0, 0);
}
@@ -283,7 +283,7 @@ void gui_401login_open(struct browser_window *bw, struct content *c,
void gui_cert_verify(struct browser_window *bw, struct content *c,
const struct ssl_cert_info *certs, unsigned long num) {}
-void global_history_add(struct url_content *data) {}
+void global_history_add(const char *url) {}
utf8_convert_ret utf8_to_local_encoding(const char *string, size_t len,
char **result)
diff --git a/gtk/gtk_thumbnail.c b/gtk/gtk_thumbnail.c
index 178014d5c..4d4fea11c 100644
--- a/gtk/gtk_thumbnail.c
+++ b/gtk/gtk_thumbnail.c
@@ -16,7 +16,7 @@
#include <assert.h>
#include <gtk/gtk.h>
#include "netsurf/content/content.h"
-#include "netsurf/content/url_store.h"
+#include "netsurf/content/urldb.h"
#include "netsurf/desktop/plotters.h"
#include "netsurf/desktop/browser.h"
#include "netsurf/image/bitmap.h"
@@ -69,7 +69,7 @@ bool thumbnail_create(struct content *content, struct bitmap *bitmap,
content->width, content->width);
gdk_pixbuf_scale(big, pixbuf, 0, 0, width, height, 0, 0,
- (double)width / (double)content->width,
+ (double)width / (double)content->width,
(double)height / (double)content->width,
GDK_INTERP_TILES);
@@ -79,7 +79,7 @@ bool thumbnail_create(struct content *content, struct bitmap *bitmap,
/* register the thumbnail with the URL */
if (url)
- url_store_add_thumbnail(url, bitmap);
+ urldb_set_thumbnail(url, bitmap);
bitmap_modified(bitmap);
diff --git a/gtk/gtk_treeview.c b/gtk/gtk_treeview.c
index 6b9280c5d..ba4214ff9 100644
--- a/gtk/gtk_treeview.c
+++ b/gtk/gtk_treeview.c
@@ -82,7 +82,8 @@ void tree_recalculate_node_element(struct node_element *element) {
*
* \param node the node to update
*/
-void tree_update_URL_node(struct node *node, struct url_content *data) {
+void tree_update_URL_node(struct node *node, const char *url,
+ const struct url_data *data) {
}
diff --git a/makefile b/makefile
index 18cfe6a6b..42b9a70ce 100644
--- a/makefile
+++ b/makefile
@@ -17,8 +17,7 @@
# "riscos", "riscos_small", "ncos", and "riscos_debug" can be compiled under
# RISC OS, or cross-compiled using GCCSDK.
-OBJECTS_COMMON = authdb.o certdb.o content.o fetch.o \
- fetchcache.o url_store.o # content/
+OBJECTS_COMMON = content.o fetch.o fetchcache.o urldb.o # content/
OBJECTS_COMMON += css.o css_enum.o parser.o ruleset.o scanner.o # css/
OBJECTS_COMMON += box.o box_construct.o box_normalise.o form.o \
html.o html_redraw.o imagemap.o layout.o list.o \
@@ -57,9 +56,10 @@ OBJECTS_DEBUG += debug_bitmap.o filetyped.o fontd.o netsurfd.o # debug/
OBJECTS_DEBUGRO = $(OBJECTS_COMMON) $(OBJECTS_IMAGE)
OBJECTS_DEBUGRO += netsurfd.o # debug/
OBJECTS_DEBUGRO += version.o # desktop/
-OBJECTS_DEBUGRO += artworks.o bitmap.o draw.o filetype.o font.o \
- gif.o gifread.o image.o jpeg.o plotters.o save_complete.o \
- schedule.o sprite.o # riscos/
+OBJECTS_DEBUGRO += artworks.o awrender.o bitmap.o draw.o \
+ filename.o filetype.o font.o gif.o gifread.o image.o \
+ jpeg.o palettes.o plotters.o save_complete.o schedule.o \
+ sprite.o # riscos/
OBJECTS_GTK = $(OBJECTS_COMMON) $(OBJECTS_IMAGE)
OBJECTS_GTK += filetyped.o # debug/
@@ -112,7 +112,7 @@ WARNFLAGS = -W -Wall -Wundef -Wpointer-arith -Wcast-qual \
# CFLAGS have to appear after the inclusion of platform specific files as the
# PLATFORM_CFLAGS variables are defined in them
-CFLAGS_RISCOS = -std=c9x -D_BSD_SOURCE -Driscos -DBOOL_DEFINED -O \
+CFLAGS_RISCOS = -std=c9x -D_BSD_SOURCE -D_POSIX_C_SOURCE -Driscos -DBOOL_DEFINED -O \
$(WARNFLAGS) -I.. $(PLATFORM_CFLAGS_RISCOS) -mpoke-function-name \
# -include netsurf/utils/memdebug.h
CFLAGS_RISCOS_SMALL = $(CFLAGS_RISCOS) -Dsmall
diff --git a/posix.mk b/posix.mk
index 33da3d035..d68f8c122 100644
--- a/posix.mk
+++ b/posix.mk
@@ -7,13 +7,14 @@ ASM = $(GCCSDK_INSTALL_CROSSBIN)/gcc
PLATFORM_CFLAGS_RISCOS = -I$(GCCSDK_INSTALL_ENV)/include \
-I$(GCCSDK_INSTALL_ENV)/include/libxml2 \
- -I$(GCCSDK_INSTALL_ENV)/include/libmng
+ -I$(GCCSDK_INSTALL_ENV)/include/libmng \
+ #-finstrument-functions
PLATFORM_CFLAGS_DEBUG = -I/usr/include/libxml2 -I/riscos/src/OSLib \
-I/riscos/include/libjpeg -D_POSIX_C_SOURCE
PLATFORM_AFLAGS_RISCOS = -I$(GCCSDK_INSTALL_ENV)/include
LDFLAGS_RISCOS = -L$(GCCSDK_INSTALL_ENV)/lib -lxml2 -lz -lcurl -lssl -lcrypto \
- -lcares -lmng -lOSLib32 -ljpeg -lrufl -lpencil
+ -lcares -lmng -lOSLib32 -ljpeg -lrufl -lpencil #-lprof
LDFLAGS_SMALL = -L$(GCCSDK_INSTALL_ENV)/lib -lxml2 -lz -lucurl \
-lcares -lmng -lOSLib32 -ljpeg -lrufl -lpencil
LDFLAGS_DEBUG = -L/usr/lib -lxml2 -lz -lm -lcurl -lssl -lcrypto -ldl -lmng \
diff --git a/riscos/401login.c b/riscos/401login.c
index ecc99e4f7..92bfe0f1a 100644
--- a/riscos/401login.c
+++ b/riscos/401login.c
@@ -12,8 +12,8 @@
#include <string.h>
#include "oslib/wimp.h"
#include "netsurf/utils/config.h"
-#include "netsurf/content/authdb.h"
#include "netsurf/content/content.h"
+#include "netsurf/content/urldb.h"
#include "netsurf/desktop/browser.h"
#include "netsurf/desktop/401login.h"
#include "netsurf/desktop/gui.h"
@@ -187,11 +187,7 @@ bool ro_gui_401login_apply(wimp_w w)
sprintf(auth, "%s:%s", session->uname, session->pwd);
- if (!authdb_insert(session->url, session->realm, auth)) {
- LOG(("failed"));
- free(auth);
- return false;
- }
+ urldb_set_auth_details(session->url, session->realm, auth);
free(auth);
diff --git a/riscos/global_history.c b/riscos/global_history.c
index cf1f3ab09..984df358c 100644
--- a/riscos/global_history.c
+++ b/riscos/global_history.c
@@ -17,7 +17,7 @@
#include <time.h>
#include "oslib/wimp.h"
#include "oslib/wimpspriteop.h"
-#include "netsurf/content/url_store.h"
+#include "netsurf/content/urldb.h"
#include "netsurf/desktop/tree.h"
#include "netsurf/riscos/dialog.h"
#include "netsurf/riscos/global_history.h"
@@ -50,20 +50,19 @@ static void ro_gui_global_history_initialise_nodes(void);
static void ro_gui_global_history_initialise_node(const char *title,
time_t base, int days_back);
static struct node *ro_gui_global_history_find(const char *url);
+static bool global_history_iterate_callback(const char *url);
-/* The history window, toolbar and plot origins
-*/
+/* The history window, toolbar and plot origins */
static wimp_w global_history_window;
struct tree *global_history_tree;
-void ro_gui_global_history_initialise(void) {
+/**
+ * Initialise global history tree
+ */
+void ro_gui_global_history_initialise(void)
+{
char s[MAXIMUM_URL_LENGTH];
FILE *fp;
- struct hostname_data *hostname;
- struct url_data *url;
- int url_count = 0;
- struct url_content **url_block;
- int i = 0;
/* create our window */
global_history_window = ro_gui_dialog_create("tree");
@@ -76,8 +75,7 @@ void ro_gui_global_history_initialise(void) {
ro_gui_wimp_event_register_mouse_click(global_history_window,
ro_gui_global_history_click);
- /* Create an empty tree
- */
+ /* Create an empty tree */
global_history_tree = calloc(sizeof(struct tree), 1);
if (!global_history_tree) {
warn_user("NoMemory", 0);
@@ -99,8 +97,7 @@ void ro_gui_global_history_initialise(void) {
ro_gui_wimp_event_register_keypress(global_history_window,
ro_gui_tree_keypress);
- /* Create our toolbar
- */
+ /* Create our toolbar */
global_history_tree->toolbar = ro_gui_theme_create_toolbar(NULL,
THEME_HISTORY_TOOLBAR);
if (global_history_tree->toolbar)
@@ -121,47 +118,29 @@ void ro_gui_global_history_initialise(void) {
fclose(fp);
}
- /* count the number of URLs to add */
- for (hostname = url_store_hostnames; hostname;
- hostname = hostname->next)
- for (url = hostname->url; url; url = url->next)
- url_count++;
- if (url_count == 0)
- return;
-
- /* place pointers to the URL data in a single block of memory so
- * they can be quickly sorted */
- url_block = (struct url_content **)malloc(
- url_count * sizeof(struct url_content *));
- if (!url_block) {
- warn_user("NoMemory", 0);
- LOG(("Insufficient memory for malloc()"));
- return;
- }
- for (hostname = url_store_hostnames; hostname;
- hostname = hostname->next)
- for (url = hostname->url; url; url = url->next)
- url_block[i++] = &url->data;
- assert(i == url_count);
-
- /* sort information by the last_visit information */
- qsort(url_block, url_count, sizeof(struct url_content *),
- url_store_compare_last_visit);
-
- /* add URLs to the global history */
global_history_init = true;
- for (i = 0; i < url_count; i++)
- global_history_add(url_block[i]);
-
+ urldb_iterate_entries(global_history_iterate_callback);
global_history_init = false;
- free(url_block);
}
+/**
+ * Callback for urldb_iterate_entries
+ *
+ * \param url The URL
+ * \return true to continue iteration, false otherwise
+ */
+bool global_history_iterate_callback(const char *url)
+{
+ global_history_add(url);
+
+ return true;
+}
/**
* Initialises the base nodes
*/
-static void ro_gui_global_history_initialise_nodes(void) {
+void ro_gui_global_history_initialise_nodes(void)
+{
struct tm *full_time;
time_t t;
int weekday;
@@ -196,8 +175,12 @@ static void ro_gui_global_history_initialise_nodes(void) {
t, -weekday - 21);
}
-static void ro_gui_global_history_initialise_node(const char *title,
- time_t base, int days_back) {
+/**
+ * Create and initialise a node
+ */
+void ro_gui_global_history_initialise_node(const char *title,
+ time_t base, int days_back)
+{
struct tm *full_time;
char buffer[64];
struct node *node;
@@ -225,7 +208,8 @@ static void ro_gui_global_history_initialise_node(const char *title,
/**
* Saves the global history's recent URL data.
*/
-void ro_gui_global_history_save(void) {
+void ro_gui_global_history_save(void)
+{
FILE *fp;
int i;
@@ -249,8 +233,10 @@ void ro_gui_global_history_save(void) {
* Respond to a mouse click
*
* \param pointer the pointer state
+ * \return true to indicate click handled
*/
-bool ro_gui_global_history_click(wimp_pointer *pointer) {
+bool ro_gui_global_history_click(wimp_pointer *pointer)
+{
ro_gui_tree_click(pointer, global_history_tree);
if (pointer->buttons == wimp_CLICK_MENU)
ro_gui_menu_create(global_history_menu, pointer->pos.x,
@@ -268,23 +254,32 @@ bool ro_gui_global_history_click(wimp_pointer *pointer) {
* \param y the x co-ordinate to give help for
* \return the message code index
*/
-int ro_gui_global_history_help(int x, int y) {
+int ro_gui_global_history_help(int x, int y)
+{
return -1;
}
/**
* Adds to the global history
+ *
+ * \param url The URL to add
*/
-void global_history_add(struct url_content *data) {
+void global_history_add(const char *url)
+{
int i, j;
+ const struct url_data *data;
struct node *parent = NULL;
struct node *link;
struct node *node;
bool before = false;
int visit_date;
- assert(data);
+ assert(url);
+
+ data = urldb_get_url_data(url);
+ if (!data)
+ return;
visit_date = data->last_visit;
@@ -316,28 +311,27 @@ void global_history_add(struct url_content *data) {
if (!parent)
return;
- /* find any previous occurance */
- if (!global_history_init) {
- node = ro_gui_global_history_find(data->url);
- if (node) {
- /* \todo: calculate old/new positions and redraw
- * only the relevant portion */
+ /* find any previous occurance */
+ if (!global_history_init) {
+ node = ro_gui_global_history_find(url);
+ if (node) {
+ /* \todo: calculate old/new positions and redraw
+ * only the relevant portion */
tree_redraw_area(global_history_tree,
0, 0, 16384, 16384);
- tree_update_URL_node(node, data);
- tree_delink_node(node);
- tree_link_node(parent, node, false);
+ tree_update_URL_node(node, url, data);
+ tree_delink_node(node);
+ tree_link_node(parent, node, false);
tree_handle_node_changed(global_history_tree,
node, false, true);
/* ro_gui_tree_scroll_visible(hotlist_tree,
&node->data);
-*/ return;
- }
+*/ return;
+ }
}
- /* Add the node at the bottom
- */
- node = tree_create_URL_node_shared(parent, data);
+ /* Add the node at the bottom */
+ node = tree_create_URL_node_shared(parent, url, data);
if ((!global_history_init) && (node)) {
tree_redraw_area(global_history_tree,
node->box.x - NODE_INSTEP,
@@ -347,8 +341,14 @@ void global_history_add(struct url_content *data) {
}
}
-
-struct node *ro_gui_global_history_find(const char *url) {
+/**
+ * Find an entry in the global history
+ *
+ * \param url The URL to find
+ * \return Pointer to node, or NULL if not found
+ */
+struct node *ro_gui_global_history_find(const char *url)
+{
int i;
struct node *node;
struct node_element *element;
@@ -359,7 +359,7 @@ struct node *ro_gui_global_history_find(const char *url) {
node; node = node->next) {
element = tree_find_element(node,
TREE_ELEMENT_URL);
- if ((element) && (url == element->text))
+ if ((element) && !strcmp(url, element->text))
return node;
}
}
@@ -369,38 +369,35 @@ struct node *ro_gui_global_history_find(const char *url) {
/**
- * Adds a URL to the recently used list
+ * Adds an URL to the recently used list
*
- * \param url the URL to add
+ * \param url the URL to add (copied)
*/
-void global_history_add_recent(const char *url) {
- struct url_content *data;
+void global_history_add_recent(const char *url)
+{
int i;
int j = -1;
char *current;
- /* by using the url_store, we get a central char* of the string that
- * isn't going anywhere unless we tell it to */
- data = url_store_find(url);
- if (!data)
- return;
-
/* try to find a string already there */
for (i = 0; i < global_history_recent_count; i++)
- if (global_history_recent_url[i] == data->url)
+ if (global_history_recent_url[i] &&
+ !strcmp(global_history_recent_url[i], url))
j = i;
/* already at head of list */
if (j == 0)
return;
- /* add to head of list */
if (j < 0) {
+ /* add to head of list */
+ free(global_history_recent_url[
+ GLOBAL_HISTORY_RECENT_URLS - 1]);
memmove(&global_history_recent_url[1],
&global_history_recent_url[0],
(GLOBAL_HISTORY_RECENT_URLS - 1) *
sizeof(char *));
- global_history_recent_url[0] = data->url;
+ global_history_recent_url[0] = strdup(url);
global_history_recent_count++;
if (global_history_recent_count > GLOBAL_HISTORY_RECENT_URLS)
global_history_recent_count =
@@ -424,7 +421,8 @@ void global_history_add_recent(const char *url) {
* \param count set to the current number of entries in the URL array on exit
* \return the current URL array
*/
-char **global_history_get_recent(int *count) {
+char **global_history_get_recent(int *count)
+{
*count = global_history_recent_count;
return global_history_recent_url;
}
diff --git a/riscos/global_history.h b/riscos/global_history.h
index e9576ecd9..5aab7b2b4 100644
--- a/riscos/global_history.h
+++ b/riscos/global_history.h
@@ -12,8 +12,6 @@
#ifndef _NETSURF_RISCOS_GLOBALHISTORY_H_
#define _NETSURF_RISCOS_GLOBALHISTORY_H_
-#include "netsurf/content/url_store.h"
-
#define GLOBAL_HISTORY_RECENT_URLS 16
void ro_gui_global_history_initialise(void);
diff --git a/riscos/gui.c b/riscos/gui.c
index b5b7564dd..26cadd79f 100644
--- a/riscos/gui.c
+++ b/riscos/gui.c
@@ -39,7 +39,7 @@
#include "rufl.h"
#include "netsurf/utils/config.h"
#include "netsurf/content/content.h"
-#include "netsurf/content/url_store.h"
+#include "netsurf/content/urldb.h"
#include "netsurf/desktop/gui.h"
#include "netsurf/desktop/netsurf.h"
#include "netsurf/desktop/options.h"
@@ -366,7 +366,7 @@ void gui_init(int argc, char** argv)
ro_gui_choose_language();
bitmap_initialise_memory();
- url_store_load(option_url_path);
+ urldb_load(option_url_path);
nsdir_temp = getenv("NetSurf$Dir");
if (!nsdir_temp)
@@ -717,7 +717,7 @@ void gui_init2(int argc, char** argv)
void gui_quit(void)
{
bitmap_quit();
- url_store_save(option_url_save);
+ urldb_save(option_url_save);
ro_gui_window_quit();
ro_gui_global_history_save();
ro_gui_hotlist_save();
@@ -1467,7 +1467,7 @@ void ro_msg_dataload(wimp_message *message)
os_error *error;
int x, y;
bool before;
- struct url_content *data;
+ const struct url_data *data;
g = ro_gui_window_lookup(message->data.data_xfer.w);
if (g) {
@@ -1525,14 +1525,17 @@ void ro_msg_dataload(wimp_message *message)
browser_window_go(g->bw, url, 0);
} else if ((hotlist_tree) && ((wimp_w)hotlist_tree->handle ==
message->data.data_xfer.w)) {
- data = url_store_find(url);
+ data = urldb_get_url_data(url);
+ if (!data)
+ urldb_add_url(url);
+ data = urldb_get_url_data(url);
if (data) {
ro_gui_tree_get_tree_coordinates(hotlist_tree,
message->data.data_xfer.pos.x,
message->data.data_xfer.pos.y,
&x, &y);
link = tree_get_link_details(hotlist_tree, x, y, &before);
- node = tree_create_URL_node(NULL, data, title);
+ node = tree_create_URL_node(NULL, url, data, title);
tree_link_node(link, node, before);
tree_handle_node_changed(hotlist_tree, node, false, true);
tree_redraw_area(hotlist_tree, node->box.x - NODE_INSTEP, 0,
diff --git a/riscos/hotlist.c b/riscos/hotlist.c
index 914b095a2..fa67098c1 100644
--- a/riscos/hotlist.c
+++ b/riscos/hotlist.c
@@ -17,6 +17,7 @@
#include "oslib/osfile.h"
#include "oslib/wimp.h"
#include "netsurf/content/content.h"
+#include "netsurf/content/urldb.h"
#include "netsurf/desktop/tree.h"
#include "netsurf/riscos/dialog.h"
#include "netsurf/riscos/menus.h"
@@ -48,10 +49,24 @@ struct tree *hotlist_tree;
struct node *dialog_folder_node;
struct node *dialog_entry_node;
+static const struct {
+ const char *url;
+ const char *msg_key;
+} default_entries[] = {
+ { "http://netsurf.sourceforge.net/", "HotlistHomepage" },
+ { "http://netsurf.sourceforge.net/builds/", "HotlistTestBuild" },
+ { "http://netsurf.sourceforge.net/docs", "HotlistDocumentation" },
+ { "http://sourceforge.net/tracker/?atid=464312&group_id=51719",
+ "HotlistBugTracker" },
+ { "http://sourceforge.net/tracker/?atid=464315&group_id=51719",
+ "HotlistFeatureRequest" }
+};
+#define ENTRIES_COUNT (sizeof(default_entries) / sizeof(default_entries[0]))
+
void ro_gui_hotlist_initialise(void) {
FILE *fp;
struct node *node;
- struct url_content *data;
+ const struct url_data *data;
/* create our window */
hotlist_window = ro_gui_dialog_create("tree");
@@ -68,6 +83,8 @@ void ro_gui_hotlist_initialise(void) {
*/
fp = fopen(option_hotlist_path, "r");
if (!fp) {
+ int i;
+
hotlist_tree = calloc(sizeof(struct tree), 1);
if (!hotlist_tree) {
warn_user("NoMemory", 0);
@@ -83,32 +100,18 @@ void ro_gui_hotlist_initialise(void) {
node = tree_create_folder_node(hotlist_tree->root, "NetSurf");
if (!node)
node = hotlist_tree->root;
- data = url_store_find("http://netsurf.sourceforge.net/");
- if (data) {
- tree_create_URL_node(node, data,
- messages_get("HotlistHomepage"));
- }
- data = url_store_find("http://netsurf.sourceforge.net/builds/");
- if (data) {
- tree_create_URL_node(node, data,
- messages_get("HotlistTestBuild"));
- }
- data = url_store_find("http://netsurf.sourceforge.net/docs");
- if (data) {
- tree_create_URL_node(node, data,
- messages_get("HotlistDocumentation"));
- }
- data = url_store_find("http://sourceforge.net/tracker/"
- "?atid=464312&group_id=51719");
- if (data) {
- tree_create_URL_node(node, data,
- messages_get("HotlistBugTracker"));
- }
- data = url_store_find("http://sourceforge.net/tracker/"
- "?atid=464315&group_id=51719");
- if (data) {
- tree_create_URL_node(node, data,
- messages_get("HotlistFeatureRequest"));
+
+ for (i = 0; i != ENTRIES_COUNT; i++) {
+ data = urldb_get_url_data(default_entries[i].url);
+ if (!data)
+ urldb_add_url(default_entries[i].url);
+
+ data = urldb_get_url_data(default_entries[i].url);
+ if (data) {
+ tree_create_URL_node(node,
+ default_entries[i].url, data,
+ messages_get(default_entries[i].msg_key));
+ }
}
tree_initialise(hotlist_tree);
} else {
@@ -196,7 +199,7 @@ void ro_gui_hotlist_visited(struct content *content, struct tree *tree,
element = tree_find_element(node, TREE_ELEMENT_URL);
if ((element) && (!strcmp(element->text,
content->url))) {
- tree_update_URL_node(node, NULL);
+ tree_update_URL_node(node, content->url, NULL);
tree_handle_node_changed(tree, node, true,
false);
}
@@ -270,7 +273,7 @@ bool ro_gui_hotlist_dialog_apply(wimp_w w) {
char *icon;
char *url = NULL;
url_func_result res = URL_FUNC_OK;
- struct url_content *data;
+ const struct url_data *data;
/* get our data */
if (w == dialog_entry) {
@@ -305,16 +308,20 @@ bool ro_gui_hotlist_dialog_apply(wimp_w w) {
/* update/insert our data */
if (!node) {
if (url) {
- data = url_store_find(url);
+ data = urldb_get_url_data(url);
+ if (!data)
+ urldb_add_url(url);
+
+ data = urldb_get_url_data(url);
if (!data) {
free(url);
free(title);
return false;
}
if (!data->title)
- data->title = strdup(title);
+ urldb_set_url_title(url, title);
node = dialog_entry_node = tree_create_URL_node(
- hotlist_tree->root, data, title);
+ hotlist_tree->root, url, data, title);
} else {
node = dialog_folder_node = tree_create_folder_node(
diff --git a/riscos/menus.c b/riscos/menus.c
index 12f6221ad..f44f88a27 100644
--- a/riscos/menus.c
+++ b/riscos/menus.c
@@ -20,6 +20,7 @@
#include "oslib/osgbpb.h"
#include "oslib/territory.h"
#include "oslib/wimp.h"
+#include "netsurf/content/urldb.h"
#include "netsurf/desktop/gui.h"
#include "netsurf/desktop/history_core.h"
#include "netsurf/render/box.h"
@@ -1368,7 +1369,7 @@ bool ro_gui_menu_handle_action(wimp_w owner, menu_action action,
struct node *node;
os_error *error;
char url[80];
- struct url_content *data;
+ const struct url_data *data;
ro_gui_menu_get_window_details(owner, &g, &bw, &c, &t, &tree);
@@ -1408,9 +1409,9 @@ bool ro_gui_menu_handle_action(wimp_w owner, menu_action action,
case HOTLIST_ADD_URL:
if ((!hotlist_tree) || (!c) || (!c->url))
return false;
- data = url_store_find(c->url);
+ data = urldb_get_url_data(c->url);
if (data) {
- node = tree_create_URL_node(hotlist_tree->root, data, NULL);
+ node = tree_create_URL_node(hotlist_tree->root, c->url, data, NULL);
if (node) {
tree_redraw_area(hotlist_tree,
node->box.x - NODE_INSTEP, 0,
diff --git a/riscos/sslcert.c b/riscos/sslcert.c
index 74a9ffdcd..678b78a0e 100644
--- a/riscos/sslcert.c
+++ b/riscos/sslcert.c
@@ -18,9 +18,9 @@
#include <stdio.h>
#include <string.h>
#include "oslib/wimp.h"
-#include "netsurf/content/certdb.h"
#include "netsurf/content/content.h"
#include "netsurf/content/fetch.h"
+#include "netsurf/content/urldb.h"
#include "netsurf/desktop/browser.h"
#include "netsurf/desktop/gui.h"
#include "netsurf/riscos/dialog.h"
@@ -169,10 +169,7 @@ bool ro_gui_cert_apply(wimp_w w)
assert(session);
- if (!certdb_insert(session->url)) {
- LOG(("certdb_insert failed"));
- return false;
- }
+ urldb_set_cert_permissions(session->url, true);
browser_window_go(session->bw, session->url, 0);
diff --git a/riscos/thumbnail.c b/riscos/thumbnail.c
index 2cb357ac5..e242864c2 100644
--- a/riscos/thumbnail.c
+++ b/riscos/thumbnail.c
@@ -21,7 +21,7 @@
#include "oslib/osfile.h"
#include "oslib/osspriteop.h"
#include "netsurf/content/content.h"
-#include "netsurf/content/url_store.h"
+#include "netsurf/content/urldb.h"
#include "netsurf/desktop/plotters.h"
#include "netsurf/image/bitmap.h"
#include "netsurf/render/font.h"
@@ -138,7 +138,7 @@ bool thumbnail_create(struct content *content, struct bitmap *bitmap,
/* register the thumbnail with the URL */
if (url)
- url_store_add_thumbnail(url, bitmap);
+ urldb_set_thumbnail(url, bitmap);
bitmap_modified(bitmap);
return true;
}
diff --git a/riscos/treeview.c b/riscos/treeview.c
index e1f6f536a..d91771907 100644
--- a/riscos/treeview.c
+++ b/riscos/treeview.c
@@ -20,7 +20,7 @@
#include "oslib/osbyte.h"
#include "oslib/osspriteop.h"
#include "oslib/wimp.h"
-#include "netsurf/content/url_store.h"
+#include "netsurf/content/urldb.h"
#include "netsurf/desktop/browser.h"
#include "netsurf/desktop/tree.h"
#include "netsurf/riscos/bitmap.h"
@@ -204,14 +204,14 @@ void tree_draw_node_element(struct tree *tree, struct node_element *element) {
int temp;
int toolbar_height = 0;
struct node_element *url_element;
- struct bitmap *bitmap = NULL;
+ const struct bitmap *bitmap = NULL;
struct node_update *update;
char *frame;
assert(tree);
assert(element);
assert(element->parent);
-
+
if (tree->toolbar)
toolbar_height = ro_gui_theme_toolbar_height(tree->toolbar);
@@ -294,11 +294,11 @@ void tree_draw_node_element(struct tree *tree, struct node_element *element) {
case NODE_ELEMENT_THUMBNAIL:
url_element = tree_find_element(element->parent, TREE_ELEMENT_URL);
if (url_element)
- bitmap = url_store_get_thumbnail(url_element->text);
+ bitmap = urldb_get_thumbnail(url_element->text);
if (bitmap) {
- frame = bitmap_get_buffer(bitmap);
- if (!frame)
- url_store_add_thumbnail(url_element->text, NULL);
+ frame = bitmap_get_buffer(bitmap);
+ if (!frame)
+ urldb_set_thumbnail(url_element->text, NULL);
if ((!frame) || (element->box.width == 0)) {
update = calloc(sizeof(struct node_update), 1);
if (!update)
@@ -348,7 +348,7 @@ void tree_draw_node_element(struct tree *tree, struct node_element *element) {
void tree_handle_node_changed_callback(void *p) {
struct node_update *update = p;
-
+
tree_handle_node_changed(update->tree, update->node, true, false);
free(update);
}
@@ -420,7 +420,7 @@ void tree_recalculate_node_element(struct node_element *element) {
int sprite_width;
int sprite_height;
osspriteop_flags flags;
- struct bitmap *bitmap = NULL;
+ const struct bitmap *bitmap = NULL;
struct node_element *url_element;
assert(element);
@@ -467,7 +467,7 @@ void tree_recalculate_node_element(struct node_element *element) {
case NODE_ELEMENT_THUMBNAIL:
url_element = tree_find_element(element->parent, TREE_ELEMENT_URL);
if (url_element)
- bitmap = url_store_get_thumbnail(url_element->text);
+ bitmap = urldb_get_thumbnail(url_element->text);
if (bitmap) {
/* if ((bitmap->width == 0) && (bitmap->height == 0))
frame = bitmap_get_buffer(bitmap);
@@ -523,32 +523,37 @@ void tree_set_node_sprite_folder(struct node *node) {
* The internal node dimensions are not updated.
*
* \param node the node to update
+ * \param url the URL
* \param data the data the node is linked to, or NULL for unlinked data
*/
-void tree_update_URL_node(struct node *node, struct url_content *data) {
+void tree_update_URL_node(struct node *node,
+ const char *url, const struct url_data *data) {
struct node_element *element;
char buffer[256];
-
+
assert(node);
-
+
element = tree_find_element(node, TREE_ELEMENT_URL);
if (!element)
return;
if (data) {
- /* node is linked, update */
- assert(!node->editable);
- if (data->title)
- node->data.text = data->title;
- else
- node->data.text = data->url;
+ /* node is linked, update */
+ assert(!node->editable);
+ if (!data->title)
+ urldb_set_url_title(url, url);
+
+ if (!data->title)
+ return;
+
+ node->data.text = data->title;
} else {
- /* node is not link, find data */
- assert(node->editable);
- data = url_store_find(element->text);
+ /* node is not linked, find data */
+ assert(node->editable);
+ data = urldb_get_url_data(element->text);
if (!data)
return;
}
-
+
if (element) {
sprintf(buffer, "small_%.3x", ro_content_filetype_from_type(data->type));
if (ro_gui_wimp_sprite_exists(buffer))
@@ -615,7 +620,7 @@ void ro_gui_tree_redraw(wimp_draw *redraw) {
struct tree *tree;
osbool more;
int clip_x0, clip_x1, clip_y0, clip_y1, origin_x, origin_y;
-
+
tree = (struct tree *)ro_gui_wimp_event_get_user_data(redraw->w);
assert(tree);
@@ -785,7 +790,7 @@ bool ro_gui_tree_click(wimp_pointer *pointer, struct tree *tree) {
element = &last->data;
if (last->expanded)
for (; element->next; element = element->next);
- ro_gui_tree_scroll_visible(tree, element);
+ ro_gui_tree_scroll_visible(tree, element);
ro_gui_tree_scroll_visible(tree, &node->data);
return true;
}
@@ -926,7 +931,7 @@ bool ro_gui_tree_toolbar_click(wimp_pointer* pointer) {
struct tree *tree =
(struct tree *)ro_gui_wimp_event_get_user_data(toolbar->parent_handle);
assert(tree);
-
+
ro_gui_tree_stop_edit(tree);
if (pointer->buttons == wimp_CLICK_MENU) {
@@ -937,7 +942,7 @@ bool ro_gui_tree_toolbar_click(wimp_pointer* pointer) {
if (tree->toolbar->editor) {
ro_gui_theme_toolbar_editor_click(tree->toolbar, pointer);
- return true;
+ return true;
}
switch (pointer->i) {
@@ -1156,9 +1161,9 @@ void ro_gui_tree_open(wimp_open *open) {
int width;
int height;
int toolbar_height = 0;
-
+
tree = (struct tree *)ro_gui_wimp_event_get_user_data(open->w);
-
+
if (!tree)
return;
if (tree->toolbar)
@@ -1264,7 +1269,7 @@ void ro_gui_tree_selection_drag_end(wimp_dragged *drag) {
os_error *error;
int x0, y0, x1, y1;
int toolbar_height = 0;
-
+
if (ro_gui_tree_current_drag_tree->toolbar)
toolbar_height = ro_gui_theme_toolbar_height(
ro_gui_tree_current_drag_tree->toolbar);
diff --git a/riscos/url_complete.c b/riscos/url_complete.c
index 88b2ad8e5..c31e0150d 100644
--- a/riscos/url_complete.c
+++ b/riscos/url_complete.c
@@ -15,7 +15,7 @@
#include <stdlib.h>
#include <string.h>
#include "oslib/wimp.h"
-#include "netsurf/content/url_store.h"
+#include "netsurf/content/urldb.h"
#include "netsurf/utils/log.h"
#include "netsurf/riscos/global_history.h"
#include "netsurf/riscos/gui.h"
@@ -27,7 +27,7 @@
#define MAXIMUM_VISIBLE_LINES 7
-static struct url_content **url_complete_matches = NULL;
+static char **url_complete_matches = NULL;
static int url_complete_matches_allocated = 0;
static int url_complete_matches_available = 0;
static char *url_complete_matched_string = NULL;
@@ -36,8 +36,9 @@ static int url_complete_keypress_selection = -1;
static wimp_w url_complete_parent = 0;
static bool url_complete_matches_reset = false;
static char *url_complete_original_url = NULL;
+static bool url_complete_memory_exhausted = false;
-static struct url_content *url_complete_redraw[MAXIMUM_VISIBLE_LINES];
+static char *url_complete_redraw[MAXIMUM_VISIBLE_LINES];
static char url_complete_icon_null[] = "\0";
static char url_complete_icon_sprite[12];
static wimp_icon url_complete_icon;
@@ -45,21 +46,26 @@ static wimp_icon url_complete_sprite;
static int mouse_x;
static int mouse_y;
+static bool url_complete_callback(const char *url);
+
/**
* Should be called when the caret is placed into a URL completion icon.
*
* \param g the gui_window to initialise URL completion for
*/
-void ro_gui_url_complete_start(struct gui_window *g) {
- char *url;
-
+void ro_gui_url_complete_start(struct gui_window *g)
+{
+ char *url;
+
if ((!g->toolbar) || (!g->toolbar->display_url) ||
(g->window == url_complete_parent))
return;
ro_gui_url_complete_close(NULL, 0);
- url = ro_gui_get_icon_string(g->toolbar->toolbar_handle, ICON_TOOLBAR_URL);
- url_complete_matched_string = url_store_match_string(url);
+ url = ro_gui_get_icon_string(g->toolbar->toolbar_handle,
+ ICON_TOOLBAR_URL);
+
+ url_complete_matched_string = strdup(url);
if (url_complete_matched_string)
url_complete_parent = g->window;
}
@@ -70,14 +76,13 @@ void ro_gui_url_complete_start(struct gui_window *g) {
*
* \param g the gui_window to update
* \param key the key pressed
+ * \return true to indicate keypress handled, false otherwise
*/
-bool ro_gui_url_complete_keypress(struct gui_window *g, int key) {
+bool ro_gui_url_complete_keypress(struct gui_window *g, int key)
+{
wimp_window_state state;
- struct url_content **array_extend;
- struct url_data *reference = NULL;
char *match_url;
char *url;
- struct url_content *output;
int i, lines;
int old_selection;
bool ignore_changes = false;
@@ -86,7 +91,8 @@ bool ro_gui_url_complete_keypress(struct gui_window *g, int key) {
bool currently_open;
/* we must have a toolbar/url bar */
- if ((!g->toolbar) || (!g->toolbar->display_url) || (!option_url_suggestion)) {
+ if ((!g->toolbar) || (!g->toolbar->display_url) ||
+ (!option_url_suggestion)) {
ro_gui_url_complete_close(NULL, 0);
return false;
}
@@ -107,12 +113,13 @@ bool ro_gui_url_complete_keypress(struct gui_window *g, int key) {
url_complete_matched_string = NULL;
}
}
-
+
/* get the text to match */
url_complete_parent = g->window;
- url = ro_gui_get_icon_string(g->toolbar->toolbar_handle, ICON_TOOLBAR_URL);
- match_url = url_store_match_string(url);
+ url = ro_gui_get_icon_string(g->toolbar->toolbar_handle,
+ ICON_TOOLBAR_URL);
+ match_url = strdup(url);
if (!match_url) {
ro_gui_url_complete_close(NULL, 0);
return false;
@@ -121,7 +128,8 @@ bool ro_gui_url_complete_keypress(struct gui_window *g, int key) {
/* check if we should ignore text changes */
if ((url_complete_keypress_selection >= 0) && (url_complete_matches))
ignore_changes = !strcmp(url,
- url_complete_matches[url_complete_keypress_selection]->url);
+ url_complete_matches[
+ url_complete_keypress_selection]);
/* if the text to match has changed then update it */
if (!ignore_changes && ((!url_complete_matched_string) ||
@@ -133,11 +141,13 @@ bool ro_gui_url_complete_keypress(struct gui_window *g, int key) {
lines = url_complete_matches_available;
if (url_complete_matches)
for (i = 0; i < MAXIMUM_VISIBLE_LINES; i++)
- url_complete_redraw[i] = url_complete_matches[i];
+ url_complete_redraw[i] =
+ url_complete_matches[i];
/* our selection gets wiped */
error = xwimp_force_redraw(dialog_url_complete,
- 0, -(url_complete_matches_selection + 1) * 44,
+ 0,
+ -(url_complete_matches_selection + 1) * 44,
65536, -url_complete_matches_selection * 44);
if (error) {
LOG(("xwimp_force_redraw: 0x%x: %s",
@@ -150,7 +160,14 @@ bool ro_gui_url_complete_keypress(struct gui_window *g, int key) {
free(url_complete_matched_string);
url_complete_matched_string = match_url;
url_complete_original_url = NULL;
- url_complete_matches_available = 0;
+ if (url_complete_matches) {
+ for (; url_complete_matches_available > 0;
+ url_complete_matches_available--)
+ free(url_complete_matches[
+ url_complete_matches_available - 1]);
+ } else {
+ url_complete_matches_available = 0;
+ }
url_complete_matches_selection = -1;
url_complete_keypress_selection = -1;
@@ -164,25 +181,12 @@ bool ro_gui_url_complete_keypress(struct gui_window *g, int key) {
url_complete_matches_allocated = 64;
}
- /* get all our matches */
- while ((output = url_store_match(match_url, &reference))) {
- url_complete_matches_available++;
- if (url_complete_matches_available >
- url_complete_matches_allocated) {
-
- array_extend = (struct url_content **)realloc(
- url_complete_matches,
- (url_complete_matches_allocated + 64) *
- sizeof(struct url_content *));
- if (!array_extend) {
- ro_gui_url_complete_close(NULL, 0);
- return false;
- }
- url_complete_matches = array_extend;
- url_complete_matches_allocated += 64;
- }
- url_complete_matches[url_complete_matches_available - 1] =
- output;
+ /* find matches */
+ url_complete_memory_exhausted = false;
+ urldb_iterate_partial(match_url, url_complete_callback);
+ if (url_complete_memory_exhausted) {
+ ro_gui_url_complete_close(NULL, 0);
+ return false;
}
/* update the window */
@@ -203,17 +207,19 @@ bool ro_gui_url_complete_keypress(struct gui_window *g, int key) {
if (lines > url_complete_matches_available)
lines = url_complete_matches_available;
for (i = 0; i < lines; i++) {
- if (url_complete_redraw[i] != url_complete_matches[i]) {
+ if (url_complete_redraw[i] !=
+ url_complete_matches[i]) {
error = xwimp_force_redraw(dialog_url_complete,
0, -(i + 1) * 44, 65536, -i * 44);
if (error) {
LOG(("xwimp_force_redraw: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
+ error->errnum,
+ error->errmess));
+ warn_user("WimpError",
+ error->errmess);
}
}
}
-
} else {
free(match_url);
}
@@ -221,7 +227,9 @@ bool ro_gui_url_complete_keypress(struct gui_window *g, int key) {
/* handle keypresses */
if (!currently_open)
return false;
+
old_selection = url_complete_matches_selection;
+
switch (key) {
case wimp_KEY_UP:
url_complete_matches_selection--;
@@ -230,10 +238,12 @@ bool ro_gui_url_complete_keypress(struct gui_window *g, int key) {
url_complete_matches_selection++;
break;
case wimp_KEY_PAGE_UP:
- url_complete_matches_selection -= MAXIMUM_VISIBLE_LINES;
+ url_complete_matches_selection -=
+ MAXIMUM_VISIBLE_LINES;
break;
case wimp_KEY_PAGE_DOWN:
- url_complete_matches_selection += MAXIMUM_VISIBLE_LINES;
+ url_complete_matches_selection +=
+ MAXIMUM_VISIBLE_LINES;
break;
case wimp_KEY_CONTROL | wimp_KEY_UP:
url_complete_matches_selection = 0;
@@ -242,8 +252,11 @@ bool ro_gui_url_complete_keypress(struct gui_window *g, int key) {
url_complete_matches_selection = 65536;
break;
}
- if (url_complete_matches_selection > url_complete_matches_available - 1)
- url_complete_matches_selection = url_complete_matches_available - 1;
+
+ if (url_complete_matches_selection >
+ url_complete_matches_available - 1)
+ url_complete_matches_selection =
+ url_complete_matches_available - 1;
else if (url_complete_matches_selection < -1)
url_complete_matches_selection = -1;
@@ -251,12 +264,14 @@ bool ro_gui_url_complete_keypress(struct gui_window *g, int key) {
return false;
error = xwimp_force_redraw(dialog_url_complete,
- 0, -(old_selection + 1) * 44, 65536, -old_selection * 44);
+ 0, -(old_selection + 1) * 44,
+ 65536, -old_selection * 44);
if (error) {
LOG(("xwimp_force_redraw: 0x%x: %s",
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
}
+
error = xwimp_force_redraw(dialog_url_complete,
0, -(url_complete_matches_selection + 1) * 44,
65536, -url_complete_matches_selection * 44);
@@ -265,6 +280,7 @@ bool ro_gui_url_complete_keypress(struct gui_window *g, int key) {
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
}
+
if (old_selection == -1) {
free(url_complete_original_url);
url_complete_original_url = malloc(strlen(url) + 1);
@@ -272,6 +288,7 @@ bool ro_gui_url_complete_keypress(struct gui_window *g, int key) {
return false;
strcpy(url_complete_original_url, url);
}
+
if (url_complete_matches_selection == -1) {
ro_gui_set_icon_string(g->toolbar->toolbar_handle,
ICON_TOOLBAR_URL,
@@ -279,7 +296,8 @@ bool ro_gui_url_complete_keypress(struct gui_window *g, int key) {
} else {
ro_gui_set_icon_string(g->toolbar->toolbar_handle,
ICON_TOOLBAR_URL,
- url_complete_matches[url_complete_matches_selection]->url);
+ url_complete_matches[
+ url_complete_matches_selection]);
}
url_complete_keypress_selection = url_complete_matches_selection;
@@ -292,11 +310,15 @@ bool ro_gui_url_complete_keypress(struct gui_window *g, int key) {
warn_user("WimpError", error->errmess);
return true;
}
+
if (state.yscroll < -(url_complete_matches_selection * 44))
state.yscroll = -(url_complete_matches_selection * 44);
height = state.visible.y1 - state.visible.y0;
- if (state.yscroll - height > -((url_complete_matches_selection + 1) * 44))
- state.yscroll = -((url_complete_matches_selection + 1) * 44) + height;
+ if (state.yscroll - height >
+ -((url_complete_matches_selection + 1) * 44))
+ state.yscroll =
+ -((url_complete_matches_selection + 1) * 44) + height;
+
error = xwimp_open_window((wimp_open *)(&state));
if (error) {
LOG(("xwimp_open_window: 0x%x: %s",
@@ -308,6 +330,43 @@ bool ro_gui_url_complete_keypress(struct gui_window *g, int key) {
return true;
}
+/**
+ * Callback function for urldb_iterate_partial
+ *
+ * \param url URL which matches
+ * \return true to continue iteration, false otherwise
+ */
+bool url_complete_callback(const char *url)
+{
+ char **array_extend;
+ char *temp;
+
+ url_complete_matches_available++;
+
+ if (url_complete_matches_available >
+ url_complete_matches_allocated) {
+
+ array_extend = (char **)realloc(url_complete_matches,
+ (url_complete_matches_allocated + 64) *
+ sizeof(struct url_content *));
+ if (!array_extend) {
+ url_complete_memory_exhausted = true;
+ return false;
+ }
+ url_complete_matches = array_extend;
+ url_complete_matches_allocated += 64;
+ }
+
+ temp = strdup(url);
+ if (!temp) {
+ url_complete_memory_exhausted = true;
+ return false;
+ }
+
+ url_complete_matches[url_complete_matches_available - 1] = temp;
+
+ return true;
+}
/**
* Move and resize the url completion window to match the toolbar.
@@ -315,7 +374,8 @@ bool ro_gui_url_complete_keypress(struct gui_window *g, int key) {
* \param g the gui_window to update
* \param open the wimp_open request (updated on exit)
*/
-void ro_gui_url_complete_resize(struct gui_window *g, wimp_open *open) {
+void ro_gui_url_complete_resize(struct gui_window *g, wimp_open *open)
+{
os_box extent = { 0, 0, 0, 0 };
wimp_icon_state url_state;
wimp_window_state toolbar_state;
@@ -327,8 +387,9 @@ void ro_gui_url_complete_resize(struct gui_window *g, wimp_open *open) {
/* only react to our window */
if (open->w != url_complete_parent)
return;
- /* if there is no toolbar, or there is no URL bar shown, or there are
- * no URL matches, close it */
+
+ /* if there is no toolbar, or there is no URL bar shown,
+ * or there are no URL matches, close it */
if ((!g->toolbar) || (!g->toolbar->display_url) ||
(!url_complete_matches) ||
(url_complete_matches_available == 0)) {
@@ -345,6 +406,7 @@ void ro_gui_url_complete_resize(struct gui_window *g, wimp_open *open) {
warn_user("WimpError", error->errmess);
return;
}
+
if (url_complete_matches_reset)
state.yscroll = 0;
@@ -357,6 +419,7 @@ void ro_gui_url_complete_resize(struct gui_window *g, wimp_open *open) {
warn_user("WimpError", error->errmess);
return;
}
+
url_state.w = g->toolbar->toolbar_handle;
url_state.i = ICON_TOOLBAR_SURROUND;
error = xwimp_get_icon_state(&url_state);
@@ -366,6 +429,7 @@ void ro_gui_url_complete_resize(struct gui_window *g, wimp_open *open) {
warn_user("WimpError", error->errmess);
return;
}
+
lines = url_complete_matches_available;
extent.y0 = -(lines * 44);
extent.x1 = 65536;
@@ -376,6 +440,7 @@ void ro_gui_url_complete_resize(struct gui_window *g, wimp_open *open) {
warn_user("WimpError", error->errmess);
return;
}
+
state.next = open->next;
state.flags &= ~wimp_WINDOW_VSCROLL;
state.flags &= ~(4095 << 16); /* clear bits 16-27 */
@@ -385,7 +450,8 @@ void ro_gui_url_complete_resize(struct gui_window *g, wimp_open *open) {
state.flags |= wimp_WINDOW_VSCROLL;
}
state.visible.x0 = open->visible.x0 + 2 + url_state.icon.extent.x0;
- state.visible.x1 = open->visible.x0 - 2 + url_state.icon.extent.x1 - scroll_v;
+ state.visible.x1 = open->visible.x0 - 2 +
+ url_state.icon.extent.x1 - scroll_v;
state.visible.y1 = open->visible.y1 - url_state.icon.extent.y1 + 2;
state.visible.y0 = state.visible.y1 - (lines * 44);
if (state.visible.x1 + scroll_v > toolbar_state.visible.x1)
@@ -398,7 +464,8 @@ void ro_gui_url_complete_resize(struct gui_window *g, wimp_open *open) {
warn_user("WimpError", error->errmess);
}
} else {
- error = xwimp_open_window_nested_with_flags(&state, (wimp_w)-1, 0);
+ error = xwimp_open_window_nested_with_flags(&state,
+ (wimp_w)-1, 0);
if (error) {
LOG(("xwimp_open_window: 0x%x: %s",
error->errnum, error->errmess));
@@ -417,16 +484,24 @@ void ro_gui_url_complete_resize(struct gui_window *g, wimp_open *open) {
* \param i the icon the user clicked on to prompt the close
* \return whether the window was closed
*/
-bool ro_gui_url_complete_close(struct gui_window *g, wimp_i i) {
+bool ro_gui_url_complete_close(struct gui_window *g, wimp_i i)
+{
os_error *error;
bool currently_open;
- if ((g && (i == ICON_TOOLBAR_URL) && (g->window == url_complete_parent)))
+ if ((g && (i == ICON_TOOLBAR_URL) &&
+ (g->window == url_complete_parent)))
return false;
currently_open = ((url_complete_parent) &&
(url_complete_matches_available > 0));
+ if (url_complete_matches) {
+ for (; url_complete_matches_available > 0;
+ url_complete_matches_available--)
+ free(url_complete_matches[
+ url_complete_matches_available - 1]);
+ }
free(url_complete_matches);
free(url_complete_matched_string);
free(url_complete_original_url);
@@ -445,6 +520,7 @@ bool ro_gui_url_complete_close(struct gui_window *g, wimp_i i) {
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
}
+
return currently_open;
}
@@ -453,13 +529,15 @@ bool ro_gui_url_complete_close(struct gui_window *g, wimp_i i) {
* Redraws a section of the URL completion window
*
* \param redraw the area to redraw
- * \param tree the tree to redraw
*/
-void ro_gui_url_complete_redraw(wimp_draw *redraw) {
+void ro_gui_url_complete_redraw(wimp_draw *redraw)
+{
osbool more;
os_error *error;
int clip_y0, clip_y1, origin_y;
int first_line, last_line, line;
+ const struct url_data *data;
+ int type;
/* initialise our icon */
url_complete_icon.flags = wimp_ICON_INDIRECTED | wimp_ICON_VCENTRED |
@@ -468,23 +546,26 @@ void ro_gui_url_complete_redraw(wimp_draw *redraw) {
(wimp_COLOUR_WHITE << wimp_ICON_BG_COLOUR_SHIFT);
url_complete_icon.extent.x0 = 50;
url_complete_icon.extent.x1 = 16384;
- url_complete_icon.data.indirected_text.validation = url_complete_icon_null;
+ url_complete_icon.data.indirected_text.validation =
+ url_complete_icon_null;
url_complete_sprite.flags = wimp_ICON_TEXT | wimp_ICON_SPRITE |
wimp_ICON_INDIRECTED | wimp_ICON_FILLED |
wimp_ICON_HCENTRED | wimp_ICON_VCENTRED;
url_complete_sprite.extent.x0 = 0;
url_complete_sprite.extent.x1 = 50;
- url_complete_sprite.data.indirected_text.text = url_complete_icon_null;
- url_complete_sprite.data.indirected_text.validation = url_complete_icon_sprite;
+ url_complete_sprite.data.indirected_text.text =
+ url_complete_icon_null;
+ url_complete_sprite.data.indirected_text.validation =
+ url_complete_icon_sprite;
url_complete_sprite.data.indirected_text.size = 1;
/* no matches? no redraw */
if (!url_complete_matches) {
- LOG(("Attempt to redraw with no matches made"));
+ LOG(("Attempt to redraw with no matches made"));
ro_gui_user_redraw(redraw, false, NULL);
return;
}
-
+
/* redraw */
more = wimp_redraw_window(redraw);
while (more) {
@@ -497,32 +578,47 @@ void ro_gui_url_complete_redraw(wimp_draw *redraw) {
for (line = first_line; line < last_line; line++) {
if (line == url_complete_matches_selection)
- url_complete_icon.flags |= wimp_ICON_SELECTED;
+ url_complete_icon.flags |=
+ wimp_ICON_SELECTED;
else
- url_complete_icon.flags &= ~wimp_ICON_SELECTED;
+ url_complete_icon.flags &=
+ ~wimp_ICON_SELECTED;
url_complete_icon.extent.y1 = -line * 44;
url_complete_icon.extent.y0 = -(line + 1) * 44;
url_complete_icon.data.indirected_text.text =
- url_complete_matches[line]->url;
+ url_complete_matches[line];
url_complete_icon.data.indirected_text.size =
- strlen(url_complete_matches[line]->url);
+ strlen(url_complete_matches[line]);
+
error = xwimp_plot_icon(&url_complete_icon);
if (error) {
LOG(("xwimp_plot_icon: 0x%x: %s",
- error->errnum, error->errmess));
+ error->errnum,
+ error->errmess));
warn_user("WimpError", error->errmess);
}
+
+ data = urldb_get_url_data(url_complete_matches[line]);
+ if (data)
+ type = ro_content_filetype_from_type(
+ data->type);
+ else
+ type = 0;
+
sprintf(url_complete_icon_sprite, "Ssmall_%.3x",
- ro_content_filetype_from_type(
- url_complete_matches[line]->type));
- if (!ro_gui_wimp_sprite_exists(url_complete_icon_sprite + 1))
- sprintf(url_complete_icon_sprite, "Ssmall_xxx");
+ type);
+
+ if (!ro_gui_wimp_sprite_exists(
+ url_complete_icon_sprite + 1))
+ sprintf(url_complete_icon_sprite,
+ "Ssmall_xxx");
url_complete_sprite.extent.y1 = -line * 44;
url_complete_sprite.extent.y0 = -(line + 1) * 44;
error = xwimp_plot_icon(&url_complete_sprite);
if (error) {
LOG(("xwimp_plot_icon: 0x%x: %s",
- error->errnum, error->errmess));
+ error->errnum,
+ error->errmess));
warn_user("WimpError", error->errmess);
}
}
@@ -536,7 +632,8 @@ void ro_gui_url_complete_redraw(wimp_draw *redraw) {
*
* \param pointer the pointer state
*/
-void ro_gui_url_complete_mouse_at(wimp_pointer *pointer) {
+void ro_gui_url_complete_mouse_at(wimp_pointer *pointer)
+{
wimp_mouse_state current;
current = pointer->buttons;
@@ -552,7 +649,8 @@ void ro_gui_url_complete_mouse_at(wimp_pointer *pointer) {
* \param pointer the pointer state
* \return whether the click was handled
*/
-bool ro_gui_url_complete_click(wimp_pointer *pointer) {
+bool ro_gui_url_complete_click(wimp_pointer *pointer)
+{
wimp_window_state state;
os_error *error;
int selection, old_selection;
@@ -562,6 +660,7 @@ bool ro_gui_url_complete_click(wimp_pointer *pointer) {
if ((mouse_x == pointer->pos.x) && (mouse_y == pointer->pos.y) &&
(!pointer->buttons))
return false;
+
mouse_x = pointer->pos.x;
mouse_y = pointer->pos.y;
@@ -573,13 +672,15 @@ bool ro_gui_url_complete_click(wimp_pointer *pointer) {
warn_user("WimpError", error->errmess);
return false;
}
+
selection = (state.visible.y1 - pointer->pos.y - state.yscroll) / 44;
if (selection != url_complete_matches_selection) {
if (url_complete_matches_selection == -1) {
g = ro_gui_window_lookup(url_complete_parent);
if (!g)
return false;
- url = ro_gui_get_icon_string(g->toolbar->toolbar_handle,
+ url = ro_gui_get_icon_string(
+ g->toolbar->toolbar_handle,
ICON_TOOLBAR_URL);
free(url_complete_original_url);
url_complete_original_url = malloc(strlen(url) + 1);
@@ -590,7 +691,8 @@ bool ro_gui_url_complete_click(wimp_pointer *pointer) {
old_selection = url_complete_matches_selection;
url_complete_matches_selection = selection;
error = xwimp_force_redraw(dialog_url_complete,
- 0, -(old_selection + 1) * 44, 65536, -old_selection * 44);
+ 0, -(old_selection + 1) * 44,
+ 65536, -old_selection * 44);
if (error) {
LOG(("xwimp_force_redraw: 0x%x: %s",
error->errnum, error->errmess));
@@ -607,7 +709,7 @@ bool ro_gui_url_complete_click(wimp_pointer *pointer) {
}
if (!pointer->buttons)
return true;
-
+
/* find owning window */
g = ro_gui_window_lookup(url_complete_parent);
if (!g)
@@ -617,18 +719,22 @@ bool ro_gui_url_complete_click(wimp_pointer *pointer) {
if (pointer->buttons == wimp_CLICK_SELECT) {
ro_gui_set_icon_string(g->toolbar->toolbar_handle,
ICON_TOOLBAR_URL,
- url_complete_matches[url_complete_matches_selection]->url);
+ url_complete_matches[
+ url_complete_matches_selection]);
browser_window_go(g->bw,
- url_complete_matches[url_complete_matches_selection]->url,
+ url_complete_matches[
+ url_complete_matches_selection],
0);
- global_history_add_recent(url_complete_matches[url_complete_matches_selection]->url);
+ global_history_add_recent(url_complete_matches[
+ url_complete_matches_selection]);
ro_gui_url_complete_close(NULL, 0);
/* Adjust just sets the text */
} else if (pointer->buttons == wimp_CLICK_ADJUST) {
ro_gui_set_icon_string(g->toolbar->toolbar_handle,
ICON_TOOLBAR_URL,
- url_complete_matches[url_complete_matches_selection]->url);
+ url_complete_matches[
+ url_complete_matches_selection]);
ro_gui_url_complete_keypress(g, 0);
}
return true;
diff --git a/riscos/window.c b/riscos/window.c
index cb66962df..cf9238bd5 100644
--- a/riscos/window.c
+++ b/riscos/window.c
@@ -30,7 +30,7 @@
#include "oslib/wimpspriteop.h"
#include "netsurf/utils/config.h"
#include "netsurf/content/content.h"
-#include "netsurf/content/url_store.h"
+#include "netsurf/content/urldb.h"
#include "netsurf/css/css.h"
#include "netsurf/desktop/browser.h"
#include "netsurf/desktop/plotters.h"
@@ -2015,6 +2015,10 @@ bool ro_gui_window_keypress(struct gui_window *g, int key, bool toolbar)
}
return true;
+ case wimp_KEY_CONTROL + wimp_KEY_F9:
+ urldb_dump();
+ return true;
+
case wimp_KEY_CONTROL + wimp_KEY_SHIFT + wimp_KEY_F9:
talloc_report_full(0, stderr);
return true;
diff --git a/utils/url.c b/utils/url.c
index c696659f4..352241e30 100644
--- a/utils/url.c
+++ b/utils/url.c
@@ -618,6 +618,65 @@ url_func_result url_strip_lqf(const char *url, char **result)
/**
+ * Extract path, leafname and query segments from an URL
+ *
+ * \param url an absolute URL
+ * \param result pointer to pointer to buffer to hold result
+ * \return URL_FUNC_OK on success
+ */
+
+url_func_result url_plq(const char *url, char **result)
+{
+ int m, path_len = 0, query_len = 0;
+ regmatch_t match[10];
+
+ (*result) = 0;
+
+ m = regexec(&url_re, url, 10, match, 0);
+ if (m) {
+ LOG(("url '%s' failed to match regex", url));
+ return URL_FUNC_FAILED;
+ }
+ if (match[URL_RE_SCHEME].rm_so == -1 ||
+ match[URL_RE_AUTHORITY].rm_so == -1)
+ return URL_FUNC_FAILED;
+
+ if (match[URL_RE_PATH].rm_so != -1)
+ path_len = match[URL_RE_PATH].rm_eo -
+ match[URL_RE_PATH].rm_so;
+ if (match[URL_RE_QUERY].rm_so != -1)
+ query_len = match[URL_RE_QUERY].rm_eo -
+ match[URL_RE_QUERY].rm_so;
+
+ (*result) = malloc((path_len ? path_len : 1) + query_len + 1 + 1);
+ if (!(*result)) {
+ LOG(("malloc failed"));
+ return URL_FUNC_NOMEM;
+ }
+
+ m = 0;
+ if (path_len) {
+ strncpy((*result), url + match[URL_RE_PATH].rm_so,
+ path_len);
+ m += path_len;
+ }
+ else
+ (*result)[m++] = '/';
+
+ if (query_len) {
+ (*result)[m++] = '?';
+ strncpy((*result) + m, url + match[URL_RE_QUERY].rm_so,
+ query_len);
+ m += query_len;
+ }
+
+ (*result)[m] = '\0';
+
+ return URL_FUNC_OK;
+}
+
+
+/**
* Attempt to find a nice filename for a URL.
*
* \param url an absolute URL
diff --git a/utils/url.h b/utils/url.h
index 3bda22969..7dc0b12ca 100644
--- a/utils/url.h
+++ b/utils/url.h
@@ -29,6 +29,7 @@ url_func_result url_nice(const char *url, char **result,
url_func_result url_escape(const char *unescaped, char **result);
url_func_result url_canonical_root(const char *url, char **result);
url_func_result url_strip_lqf(const char *url, char **result);
+url_func_result url_plq(const char *url, char **result);
char *path_to_url(const char *path);
char *url_to_path(const char *url);