Here is the C program for a single level # with a modulo of 127.
It is basically a copy of the EXIM code. No claims about C code
but it works. The program is necessary for various administration
stripts for creating new users, deleting them, or looking for
their INBOX.
If you want to change from 127, I hope it is rather obvious.
Changes to Washington IMAP and POP2/3 to include this are given below.
(Version 4.7c)
Used with EXIM
driver = appendfile
file = "/var/mail/${nhash_127:$local_part}/$local_part/INBOX"
If you want 2 level hash then I have a similar program. I used it
to check the distribution of my userids but it gave a sparse matrix
against various modulo values. I am only dealing with approx 10,000
mailboxes whereas 2 level hashing, I believe, is for the 1,000,000s.
John Linn (j.linn@???)
------------------------------
Here is a c program to print the hash given the userid
/* nh.c
* This takes a userid as the arguement and prints out the
* single hash number using modulo 127
*/
/* set the modulo and the set of primes
*/
#include <stdio.h>
#include <stddef.h>
int value1 = 127 ;
int n;
char line[100], sub[100];
static unsigned int prime[] = {
2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
73, 79, 83, 89, 97, 101, 103, 107, 109, 113};
main (int argc, char *argv[])
{
extern char line[],sub[];
if (argc != 2)
{fprintf(stderr,"Single parameter must be a userid\n");
exit(1);}
if(strlen(argv[1]) >8)
{fprintf(stderr,"Parameter is userid - 8 characters max\n");
exit(1);}
strncpy(sub,argv[1],8);
nhash(sub);
printf("%d\n",n);
}
/* Numeric hash. The first characters of the string are treated
as most important, and get the highest prime numbers. */
nhash (sub)
char *sub;
{
char *s = sub;
int i = 0;
unsigned long int total = 0; /* no overflow */
extern n,value1;
while (*s != 0)
{
if (i == 0) i = sizeof(prime)/sizeof(int) - 1;
total += prime[i--] * (unsigned int)(*s++);
}
total = total % value1 ;
n = total;
}
-----------------
and for Washington 4.7c the diff of my env_unix.c and the original
44,55d43
< /* JAL
< *
< * externs for nhas in sysinbox change
< *
< */
< static unsigned int prime[] = {
< 2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
< 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
< 73, 79, 83, 89, 97, 101, 103, 107, 109, 113};
<
< /* JAL END */
<
656,663d643
< /* JAL add declarations */
< char *s;
< int i;
< unsigned long int total; /* no overflow */
< int value1 ;
< /* JAL */
<
<
665,690c645
< /*
< * JAL
< * replace the next line with nhash 127 userid
< *
< * sprintf (tmp,"%s/%s",MAILSPOOL,myusername ());
< *
< */
< {
< s=myusername ();
< i = 0;
< total = 0; /* no overflow */
< value1 = 127;
<
< while (*s != 0)
< {
< if (i == 0) i = sizeof(prime)/sizeof(int) - 1;
< total += prime[i--] * (unsigned int)(*s++);
< }
<
< total = total % value1 ;
< }
< sprintf (tmp,"%s/%d/%s/INBOX",MAILSPOOL,total,myusername ());
< /* print the INBOX to log file
< * syslog (LOG_INFO,"INBOX: %s",tmp);
< */
<
---
> sprintf (tmp,"%s/%s",MAILSPOOL,myusername ());