diff options
| author | Sam Varshavchik | 2013-08-19 16:39:41 -0400 | 
|---|---|---|
| committer | Sam Varshavchik | 2013-08-25 14:43:51 -0400 | 
| commit | 9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch) | |
| tree | 7a81a04cb51efb078ee350859a64be2ebc6b8813 /random128/random128.c | |
| parent | a9520698b770168d1f33d6301463bb70a19655ec (diff) | |
| download | courier-libs-9c45d9ad13fdf439d44d7443ae75da15ea0223ed.tar.bz2 | |
Initial checkin
Imported from subversion report, converted to git. Updated all paths in
scripts and makefiles, reflecting the new directory hierarchy.
Diffstat (limited to 'random128/random128.c')
| -rw-r--r-- | random128/random128.c | 125 | 
1 files changed, 125 insertions, 0 deletions
| diff --git a/random128/random128.c b/random128/random128.c new file mode 100644 index 0000000..da3b39e --- /dev/null +++ b/random128/random128.c @@ -0,0 +1,125 @@ +/* +** 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" + + +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); +} | 
