int main (void) { struct hash_table *ht = make_string_hash_table (0); char line[80]; while ((fgets (line, sizeof (line), stdin))) { int len = strlen (line); if (len <= 1) continue; line[--len] = '\0'; if (!hash_table_contains (ht, line)) hash_table_put (ht, strdup (line), "here I am!"); #if 1 if (len % 5 == 0) { char *line_copy; if (hash_table_get_pair (ht, line, &line_copy, NULL)) { hash_table_remove (ht, line); xfree (line_copy); } } #endif } #if 0 print_hash (ht); #endif #if 1 printf ("%d %d\n", ht->count, ht->size); #endif return 0; }
void register_delete_file (const char *file) { char *old_url, *old_file; ENSURE_TABLES_EXIST; if (!hash_table_get_pair (dl_file_url_map, file, &old_file, &old_url)) return; hash_table_remove (dl_file_url_map, file); xfree (old_file); xfree (old_url); dissociate_urls_from_file (file); }
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); } }
void register_download (const char *url, const char *file) { char *old_file, *old_url; ENSURE_TABLES_EXIST; /* With some forms of retrieval, it is possible, although not likely or particularly desirable. If both are downloaded, the second download will override the first one. When that happens, dissociate the old file name from the URL. */ if (hash_table_get_pair (dl_file_url_map, file, &old_file, &old_url)) { if (0 == strcmp (url, old_url)) /* We have somehow managed to download the same URL twice. Nothing to do. */ return; if (match_except_index (url, old_url) && !hash_table_contains (dl_url_file_map, url)) /* The two URLs differ only in the "index.html" ending. For example, one is "http://www.server.com/", and the other is "http://www.server.com/index.html". Don't remove the old one, just add the new one as a non-canonical entry. */ goto url_only; hash_table_remove (dl_file_url_map, file); xfree (old_file); xfree (old_url); /* Remove all the URLs that point to this file. Yes, there can be more than one such URL, because we store redirections as multiple entries in dl_url_file_map. For example, if URL1 redirects to URL2 which gets downloaded to FILE, we map both URL1 and URL2 to FILE in dl_url_file_map. (dl_file_url_map only points to URL2.) When another URL gets loaded to FILE, we want both URL1 and URL2 dissociated from it. This is a relatively expensive operation because it performs a linear search of the whole hash table, but it should be called very rarely, only when two URLs resolve to the same file name, *and* the "<file>.1" extensions are turned off. In other words, almost never. */ dissociate_urls_from_file (file); } hash_table_put (dl_file_url_map, xstrdup (file), xstrdup (url)); url_only: /* A URL->FILE mapping is not possible without a FILE->URL mapping. If the latter were present, it should have been removed by the above `if'. So we could write: assert (!hash_table_contains (dl_url_file_map, url)); The above is correct when running in recursive mode where the same URL always resolves to the same file. But if you do something like: wget URL URL then the first URL will resolve to "FILE", and the other to "FILE.1". In that case, FILE.1 will not be found in dl_file_url_map, but URL will still point to FILE in dl_url_file_map. */ if (hash_table_get_pair (dl_url_file_map, url, &old_url, &old_file)) { hash_table_remove (dl_url_file_map, url); xfree (old_url); xfree (old_file); } hash_table_put (dl_url_file_map, xstrdup (url), xstrdup (file)); }
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)); }