File: random128.c

package info (click to toggle)
courier 0.60.0-2
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 52,288 kB
  • ctags: 12,677
  • sloc: ansic: 165,348; cpp: 24,820; sh: 16,410; perl: 6,839; makefile: 3,621; yacc: 289; sed: 16
file content (126 lines) | stat: -rw-r--r-- 2,185 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*
** Copyright 1998 - 2006 Double Precision, Inc.
** See COPYING for distribution information.
*/

#if	HAVE_CONFIG_H
#include	"config.h"
#endif

#if	HAVE_UNISTD_H
#include	<unistd.h>
#endif
#if	HAVE_FCNTL_H
#include	<fcntl.h>
#endif
#include	<time.h>
#include	<string.h>
#include	<errno.h>
#include	<stdio.h>
#include	<sys/types.h>
#include	<sys/wait.h>

#define	MD5_INTERNAL
#include	"md5/md5.h"

#include	"random128.h"

static const char rcsid[]="$Id: random128.c,v 1.6 2006/05/28 15:29:52 mrsam Exp $";

const char *random128()
{
static char randombuf[sizeof(MD5_DIGEST)*2+1];

#ifdef	RANDOM
	{
	int	fd=open(RANDOM, O_RDONLY);
	char	buf2[sizeof(MD5_DIGEST)];
	int	i;

		if (fd >= 0)
		{
			if (read(fd, buf2, sizeof(buf2)) == sizeof(buf2))
			{
				for (i=0; i<sizeof(buf2); i++)
					sprintf(randombuf+i*2,
						"%02X",
						(int)(unsigned char)buf2[i]);
				close(fd);
				return (randombuf);
			}
			close(fd);
		}
	}
#endif

	/* /dev/urandom not available or broken?  Create some noise */

	{
	int pipefd[2];
	int s;
	char	buf[512];
	struct MD5_CONTEXT context;
	MD5_DIGEST	digest;
	int	n;
	time_t	t;
	pid_t	p, p2;
	unsigned long l;

		time(&t);
		p=getpid();

		if (pipe(pipefd))	return (0);
		while ((p=fork()) == -1)
		{
			sleep (5);
		}
		if (p == 0)
		{
			dup2(pipefd[1], 1);
			dup2(pipefd[1], 2);
			close(pipefd[0]);
			close(pipefd[1]);

#ifdef	W
			while ((p=fork()) == -1)
			{
				sleep (5);
			}
			if (p == 0)
			{
				execl(W, W, (char *)0);
				perror(W);
				_exit(0);
			}
			while (wait(&s) >= 0)
				;
#endif

			execl(PS, PS, PS_OPTIONS, (char *)0);
			perror(PS);
			_exit(0);
		}
		close(pipefd[1]);
		md5_context_init(&context);
		md5_context_hashstream(&context, &t, sizeof(t));
		md5_context_hashstream(&context, &p, sizeof(p));
		l=sizeof(t)+sizeof(p);

		while ((n=read(pipefd[0], buf, sizeof(buf))) > 0)
		{
			md5_context_hashstream(&context, buf, n);
			l += n;
		}
		md5_context_endstream(&context, l);
		md5_context_digest(&context, digest);
		close(pipefd[0]);
		while ((p2=wait(&s)) >= 0 && p != p2)
			;

		for (n=0; n<sizeof(digest); n++)
			sprintf(randombuf+n*2,
				"%02X", (int)(unsigned char)digest[n]);
	}

	return (randombuf);
}