struct robot_specs * res_get_specs (const char *host, int port) { char *hp; SET_HOSTPORT (host, port, hp); if (!registered_specs) return NULL; return hash_table_get (registered_specs, hp); }
static struct cookie * find_cookie_chain_exact (const char *domain, int port) { char *key; if (!cookies_hash_table) return NULL; SET_HOSTPORT (domain, port, key); return hash_table_get (cookies_hash_table, key); }
static void discard_matching_cookie (struct cookie *cookie) { struct cookie *prev, *victim; if (!cookies_hash_table || !hash_table_count (cookies_hash_table)) /* No elements == nothing to discard. */ return; victim = find_matching_cookie (cookie, &prev); if (victim) { if (prev) /* Simply unchain the victim. */ prev->next = victim->next; else { /* VICTIM was head of its chain. We need to place a new cookie at the head. */ char *hostport; char *chain_key = NULL; int res; SET_HOSTPORT (victim->domain, victim->port, hostport); res = hash_table_get_pair (cookies_hash_table, hostport, &chain_key, NULL); assert (res != 0); if (!victim->next) { /* VICTIM was the only cookie in the chain. Destroy the chain and deallocate the chain key. */ hash_table_remove (cookies_hash_table, hostport); xfree (chain_key); } else hash_table_put (cookies_hash_table, chain_key, victim->next); } delete_cookie (victim); DEBUGP (("Discarded old cookie.\n")); } }
void res_register_specs (const char *host, int port, struct robot_specs *specs) { struct robot_specs *old; char *hp, *hp_old; SET_HOSTPORT (host, port, hp); if (!registered_specs) registered_specs = make_nocase_string_hash_table (0); if (hash_table_get_pair (registered_specs, hp, &hp_old, &old)) { if (old) free_specs (old); hash_table_put (registered_specs, hp_old, specs); } else { hash_table_put (registered_specs, xstrdup (hp), specs); } }
static int find_matching_chains (const char *host, int port, struct cookie *store[], int size) { struct cookie *chain; int dot_count; char *hash_key; int count = 0; if (!cookies_hash_table) return 0; SET_HOSTPORT (host, port, hash_key); /* Exact match. */ chain = hash_table_get (cookies_hash_table, hash_key); if (chain) STORE_CHAIN (chain, store, size, count); dot_count = count_char (host, '.'); /* Match less and less specific domains. For instance, given fly.srk.fer.hr, we match .srk.fer.hr, then .fer.hr. */ while (dot_count-- > 1) { /* Note: we operate directly on hash_key (in form host:port) because we don't want to allocate new hash keys in a loop. */ char *p = strchr (hash_key, '.'); assert (p != NULL); chain = hash_table_get (cookies_hash_table, p); if (chain) STORE_CHAIN (chain, store, size, count); hash_key = p + 1; } return count; }
static void store_cookie (struct cookie *cookie) { struct cookie *chain_head; char *hostport; char *chain_key; if (!cookies_hash_table) /* If the hash table is not initialized, do so now, because we'll need to store things. */ cookies_hash_table = make_nocase_string_hash_table (0); /* Initialize hash table key. */ SET_HOSTPORT (cookie->domain, cookie->port, hostport); if (hash_table_get_pair (cookies_hash_table, hostport, &chain_key, &chain_head)) { /* There already exists a chain of cookies with this exact domain. We need to check for duplicates -- if an existing cookie exactly matches our domain, path and name, we replace it. */ struct cookie *prev; struct cookie *victim = find_matching_cookie (cookie, &prev); if (victim) { /* Remove VICTIM from the chain. COOKIE will be placed at the head. */ if (prev) { prev->next = victim->next; cookie->next = chain_head; } else { /* prev is NULL; apparently VICTIM was at the head of the chain. This place will be taken by COOKIE, so all we need to do is: */ cookie->next = victim->next; } delete_cookie (victim); DEBUGP (("Deleted old cookie (to be replaced.)\n")); } else cookie->next = chain_head; } else { /* We are now creating the chain. Allocate the string that will be used as a key. It is unsafe to use cookie->domain for that, because it might get deallocated by the above code at some point later. */ cookie->next = NULL; chain_key = xstrdup (hostport); } hash_table_put (cookies_hash_table, chain_key, cookie); DEBUGP (("\nStored cookie %s %d %s %s %d %s %s %s\n", cookie->domain, cookie->port, cookie->path, cookie->permanent ? "permanent" : "nonpermanent", cookie->secure, asctime (localtime ((time_t *)&cookie->expiry_time)), cookie->attr, cookie->value)); }