Added -messageid switch to send(1) and post(8). This allows selection
[mmh] / sbr / m_rand.c
1 /*
2  * m_rand -- provides pseudorandom bytes
3  *
4  * This code is Copyright (c) 2012, by the authors of nmh.  See the
5  * COPYRIGHT file in the root directory of the nmh distribution for
6  * complete copyright information.
7  */
8
9 #include <stdlib.h>  /* for abs(), srand(), rand() */
10 #include <stdio.h>   /* for fopen(), fread(), fclose() */
11 #include <unistd.h>  /* for getpid() */
12 #include <time.h>    /* for time() */
13
14 static int seeded = 0;
15
16
17 int
18 m_rand (unsigned char *buf, size_t n) {
19   if (! seeded) {
20     FILE *devurandom;
21     unsigned int seed;
22
23     if ((devurandom = fopen ("/dev/urandom", "r"))) {
24       if (fread (&seed, sizeof (seed), 1, devurandom) == 1) seeded = 1;
25       fclose (devurandom);
26     }
27
28     if (! seeded) {
29       /* This seed calculation is from Helmut G. Katzgraber, "Random
30          Numbers in Scientific Computing:  An Introduction",
31          arXiv:1005.4117v1 [physics.comp-ph], 22 May 2010, p. 19.
32          time() and getpid() shouldn't fail on POSIX platforms. */
33       seed = abs ((int) ((time (0) * 181 * ((getpid ()-83) * 359)) % 104729));
34       seeded = 1;
35     }
36
37     srand (seed);
38   }
39
40   while (n > 0) {
41     int rnd = rand ();
42     unsigned char *rndp = (unsigned char *) &rnd;
43     unsigned int i;
44
45     for (i = 0; i < sizeof rnd  &&  n > 0;  ++i, --n) {
46       *buf++ = *rndp++;
47     }
48   }
49
50   return 0;
51 }