[Exim] C code for nhash and Washington IMAP and POP

Top Page
Delete this message
Reply to this message
Author: sys044
Date:  
To: exim-users
Subject: [Exim] C code for nhash and Washington IMAP and POP
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 ());