From 9f6ce80da3baaa33848293fb293e51500095f13c Mon Sep 17 00:00:00 2001 From: Miciah Dashiel Butler Masters Date: Thu, 30 Aug 2007 23:36:20 +0000 Subject: [PATCH] Add config/domain.[ch] (doh!) --- src/config/domain.c | 112 ++++++++++++++++++++++++++++++++++++++++++++ src/config/domain.h | 29 ++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 src/config/domain.c create mode 100644 src/config/domain.h diff --git a/src/config/domain.c b/src/config/domain.c new file mode 100644 index 000000000..897cc5f1c --- /dev/null +++ b/src/config/domain.c @@ -0,0 +1,112 @@ +/* Domain-specific options infrastructure */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "elinks.h" + +#include "config/domain.h" +#include "config/options.h" +#include "protocol/uri.h" +#include "session/location.h" +#include "session/session.h" +#include "util/lists.h" +#include "viewer/text/vs.h" + + +INIT_LIST_OF(struct domain_tree, domain_trees); + + +/* Look for the option with the given name in all domain shadow-trees that + * match the given domain-name. Return the option from the the shadow tree + * that best matches the given domain name. */ +static struct option * +get_domain_option(unsigned char *domain_name, int domain_len, + unsigned char *name) +{ + struct option *opt, *longest_match_opt = NULL; + struct domain_tree *longest_match = NULL; + struct domain_tree *domain; + + assert(domain_name); + assert(*domain_name); + + foreach (domain, domain_trees) + if ((!longest_match || domain->len > longest_match->len) + && is_in_domain(domain->name, domain_name, domain_len) + && (opt = get_opt_rec_real(domain->tree, name))) { + longest_match = domain; + longest_match_opt = opt; + } + + return longest_match_opt; +} + +struct option * +get_domain_option_from_session(unsigned char *name, struct session *ses) +{ + struct uri *uri; + + assert(ses); + assert(name); + + if (!have_location(ses)) + return NULL; + + uri = cur_loc(ses)->vs.uri; + if (!uri->host || !uri->hostlen) + return NULL; + + return get_domain_option(uri->host, uri->hostlen, name); +} + +/* Return the shadow shadow tree for the given domain name, and + * if the domain does not yet have a shadow tree, create it. */ +struct option * +get_domain_tree(unsigned char *domain_name) +{ + struct domain_tree *domain; + int domain_len; + + assert(domain_name); + assert(*domain_name); + + foreach (domain, domain_trees) + if (!strcasecmp(domain->name, domain_name)) + return domain->tree; + + domain_len = strlen(domain_name); + /* One byte is reserved for domain in struct domain_tree. */ + domain = mem_alloc(sizeof(*domain) + domain_len); + if (!domain) return NULL; + + domain->tree = copy_option(config_options, CO_SHALLOW + | CO_NO_LISTBOX_ITEM); + if (!domain->tree) { + mem_free(domain); + return NULL; + } + + memcpy(domain->name, domain_name, domain_len + 1); + domain->len = domain_len; + + add_to_list(domain_trees, domain); + + return domain->tree; +} + +void +done_domain_trees(void) +{ + struct domain_tree *domain, *next; + + foreachsafe (domain, next, domain_trees) { + delete_option(domain->tree); + domain->tree = NULL; + del_from_list(domain); + mem_free(domain); + } +} diff --git a/src/config/domain.h b/src/config/domain.h new file mode 100644 index 000000000..726201afd --- /dev/null +++ b/src/config/domain.h @@ -0,0 +1,29 @@ +#ifndef EL__CONFIG_DOMAIN_H +#define EL__CONFIG_DOMAIN_H + +#include "config/options.h" +#include "util/lists.h" + +struct session; + + +struct domain_tree { + LIST_HEAD(struct domain_tree); + + struct option *tree; + + int len; + + unsigned char name[1]; /* Must be at end of struct. */ +}; + +extern LIST_OF(struct domain_tree) domain_trees; + +struct option *get_domain_tree(unsigned char *); + +struct option *get_domain_option_from_session(unsigned char *, + struct session *); + +void done_domain_trees(void); + +#endif