1995-11-29 07:40:04 +00:00
|
|
|
/* hash.c
|
|
|
|
|
|
|
|
Routines for manipulating hash tables... */
|
|
|
|
|
|
|
|
/*
|
1999-03-16 05:50:46 +00:00
|
|
|
* Copyright (c) 1996-1999 Internet Software Consortium.
|
|
|
|
* Use is subject to license terms which appear in the file named
|
|
|
|
* ISC-LICENSE that should have accompanied this file when you
|
|
|
|
* received it. If a file named ISC-LICENSE did not accompany this
|
|
|
|
* file, or you are not sure the one you have is correct, you may
|
|
|
|
* obtain an applicable copy of the license at:
|
1995-11-29 07:40:04 +00:00
|
|
|
*
|
1999-03-16 05:50:46 +00:00
|
|
|
* http://www.isc.org/isc-license-1.0.html.
|
1995-11-29 07:40:04 +00:00
|
|
|
*
|
1999-03-16 05:50:46 +00:00
|
|
|
* This file is part of the ISC DHCP distribution. The documentation
|
|
|
|
* associated with this file is listed in the file DOCUMENTATION,
|
|
|
|
* included in the top-level directory of this release.
|
1995-11-29 07:40:04 +00:00
|
|
|
*
|
1999-03-16 05:50:46 +00:00
|
|
|
* Support and other services are available for ISC products - see
|
|
|
|
* http://www.isc.org for more information.
|
1995-11-29 07:40:04 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef lint
|
|
|
|
static char copyright[] =
|
1999-04-12 21:33:34 +00:00
|
|
|
"$Id: hash.c,v 1.14 1999/04/12 21:33:34 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
|
1995-11-29 07:40:04 +00:00
|
|
|
#endif /* not lint */
|
|
|
|
|
|
|
|
#include "dhcpd.h"
|
|
|
|
|
1998-03-16 06:17:37 +00:00
|
|
|
static INLINE int do_hash PROTO ((unsigned char *, int, int));
|
1996-02-06 20:25:56 +00:00
|
|
|
|
1995-11-29 07:40:04 +00:00
|
|
|
struct hash_table *new_hash ()
|
|
|
|
{
|
|
|
|
struct hash_table *rv = new_hash_table (DEFAULT_HASH_SIZE, "new_hash");
|
|
|
|
if (!rv)
|
|
|
|
return rv;
|
1996-05-16 07:21:29 +00:00
|
|
|
memset (&rv -> buckets [0], 0,
|
1995-11-29 07:40:04 +00:00
|
|
|
DEFAULT_HASH_SIZE * sizeof (struct hash_bucket *));
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1996-02-06 20:25:56 +00:00
|
|
|
static INLINE int do_hash (name, len, size)
|
1998-03-16 06:17:37 +00:00
|
|
|
unsigned char *name;
|
1995-11-29 07:40:04 +00:00
|
|
|
int len;
|
|
|
|
int size;
|
|
|
|
{
|
|
|
|
register int accum = 0;
|
|
|
|
register unsigned char *s = (unsigned char *)name;
|
|
|
|
int i = len;
|
1999-04-12 21:33:34 +00:00
|
|
|
while (i--) {
|
|
|
|
/* Add the character in... */
|
|
|
|
accum += *s++;
|
|
|
|
/* Add carry back in... */
|
|
|
|
while (accum > 255) {
|
|
|
|
accum = (accum & 255) + (accum >> 8);
|
1995-11-29 07:40:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return accum % size;
|
|
|
|
}
|
|
|
|
|
|
|
|
void add_hash (table, name, len, pointer)
|
|
|
|
struct hash_table *table;
|
|
|
|
int len;
|
1998-03-16 06:17:37 +00:00
|
|
|
unsigned char *name;
|
1995-11-29 07:40:04 +00:00
|
|
|
unsigned char *pointer;
|
|
|
|
{
|
1996-05-13 00:03:27 +00:00
|
|
|
int hashno;
|
|
|
|
struct hash_bucket *bp;
|
|
|
|
|
|
|
|
if (!table)
|
|
|
|
return;
|
|
|
|
|
1999-04-05 19:02:42 +00:00
|
|
|
if (!len)
|
1999-04-12 21:33:34 +00:00
|
|
|
len = strlen ((char *)name);
|
1999-04-05 19:02:42 +00:00
|
|
|
|
1996-05-13 00:03:27 +00:00
|
|
|
hashno = do_hash (name, len, table -> hash_count);
|
|
|
|
bp = new_hash_bucket ("add_hash");
|
|
|
|
|
1995-11-29 07:40:04 +00:00
|
|
|
if (!bp) {
|
1999-02-24 17:56:53 +00:00
|
|
|
log_error ("Can't add %s to hash table.", name);
|
1995-11-29 07:40:04 +00:00
|
|
|
return;
|
|
|
|
}
|
1996-08-28 01:39:20 +00:00
|
|
|
bp -> name = name;
|
1995-11-29 07:40:04 +00:00
|
|
|
bp -> value = pointer;
|
|
|
|
bp -> next = table -> buckets [hashno];
|
1996-02-21 12:11:09 +00:00
|
|
|
bp -> len = len;
|
1995-11-29 07:40:04 +00:00
|
|
|
table -> buckets [hashno] = bp;
|
|
|
|
}
|
|
|
|
|
|
|
|
void delete_hash_entry (table, name, len)
|
|
|
|
struct hash_table *table;
|
|
|
|
int len;
|
1998-03-16 06:17:37 +00:00
|
|
|
unsigned char *name;
|
1995-11-29 07:40:04 +00:00
|
|
|
{
|
1996-05-13 00:03:27 +00:00
|
|
|
int hashno;
|
1995-11-29 07:40:04 +00:00
|
|
|
struct hash_bucket *bp, *pbp = (struct hash_bucket *)0;
|
|
|
|
|
1996-05-13 00:03:27 +00:00
|
|
|
if (!table)
|
|
|
|
return;
|
|
|
|
|
1999-04-05 19:02:42 +00:00
|
|
|
if (!len)
|
1999-04-12 21:33:34 +00:00
|
|
|
len = strlen ((char *)name);
|
1999-04-05 19:02:42 +00:00
|
|
|
|
1996-05-13 00:03:27 +00:00
|
|
|
hashno = do_hash (name, len, table -> hash_count);
|
|
|
|
|
1995-11-29 07:40:04 +00:00
|
|
|
/* Go through the list looking for an entry that matches;
|
|
|
|
if we find it, delete it. */
|
|
|
|
for (bp = table -> buckets [hashno]; bp; bp = bp -> next) {
|
1998-03-16 06:17:37 +00:00
|
|
|
if ((!bp -> len &&
|
|
|
|
!strcmp ((char *)bp -> name, (char *)name)) ||
|
1995-11-29 07:40:04 +00:00
|
|
|
(bp -> len == len &&
|
|
|
|
!memcmp (bp -> name, name, len))) {
|
|
|
|
if (pbp) {
|
|
|
|
pbp -> next = bp -> next;
|
|
|
|
} else {
|
|
|
|
table -> buckets [hashno] = bp -> next;
|
|
|
|
}
|
|
|
|
free_hash_bucket (bp, "delete_hash_entry");
|
|
|
|
break;
|
|
|
|
}
|
1996-09-09 07:04:45 +00:00
|
|
|
pbp = bp; /* jwg, 9/6/96 - nice catch! */
|
1995-11-29 07:40:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned char *hash_lookup (table, name, len)
|
|
|
|
struct hash_table *table;
|
1998-03-16 06:17:37 +00:00
|
|
|
unsigned char *name;
|
1995-11-29 07:40:04 +00:00
|
|
|
int len;
|
|
|
|
{
|
1996-05-13 00:03:27 +00:00
|
|
|
int hashno;
|
1995-11-29 07:40:04 +00:00
|
|
|
struct hash_bucket *bp;
|
|
|
|
|
1996-05-13 00:03:27 +00:00
|
|
|
if (!table)
|
|
|
|
return (unsigned char *)0;
|
1999-04-05 19:02:42 +00:00
|
|
|
if (!len)
|
1999-04-12 21:33:34 +00:00
|
|
|
len = strlen ((char *)name);
|
1999-04-05 19:02:42 +00:00
|
|
|
|
1996-05-13 00:03:27 +00:00
|
|
|
hashno = do_hash (name, len, table -> hash_count);
|
|
|
|
|
1999-04-05 19:02:42 +00:00
|
|
|
for (bp = table -> buckets [hashno]; bp; bp = bp -> next) {
|
|
|
|
if (len == bp -> len
|
|
|
|
&& !memcmp (bp -> name, name, len))
|
|
|
|
return bp -> value;
|
1995-11-29 07:40:04 +00:00
|
|
|
}
|
|
|
|
return (unsigned char *)0;
|
|
|
|
}
|
|
|
|
|