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 - */ - -/** \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 -#include -#include -#include -#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 - */ - -/** \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 - */ - -/** \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 -#include -#include -#include -#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 - */ - -/** \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 - */ - -/** \file - * Central repository for URL data (implementation). - */ - -#include -#include -#include -#include -#include -#include -#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, ¤t_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, ¤t_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 - */ - -/** \file - * Central repository for URL data (interface). - */ - -#ifndef _NETSURF_CONTENT_URLSTORE_H_ -#define _NETSURF_CONTENT_URLSTORE_H_ - -#include -#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 + */ + +/** \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 +#include +#include +#include +#include +#include +#include +#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 = ∅ + + 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 = ∅ + 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 + */ + +/** \file + * Unified URL information database (interface) + */ + +#ifndef _NETSURF_CONTENT_URLDB_H_ +#define _NETSURF_CONTENT_URLDB_H_ + +#include +#include +#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 #include #include -#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 #include #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 #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 #include #include -#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; + 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) { + 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 -#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 #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 #include #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 #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 #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 #include #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 #include #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 @@ -617,6 +617,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. * 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);