/*
* Generate a random 32-bit quantity.
*/
#include "types.h"          /* u_int32 */
#include <sys/time.h>       /* gettimeofday() */
#include <unistd.h>         /* get..() */
#include <string.h>         /* strncpy() */
#include <stdlib.h>         /* atoi() */
#include <stdio.h>          /* printf() */
#include <sys/utsname.h>    /* uname() */
#include <time.h>           /* clock() */
#include "global.h"         /* from RFC 1321 */
#include "md5.h"            /* from RFC 1321 */
extern long gethostid(void);

static char rcsid[] = "$Id: random32.c,v 1.2 1995/03/22 09:17:15 hgs Exp $";

#define MD_CTX MD5_CTX
#define MDInit MD5Init
#define MDUpdate MD5Update
#define MDFinal MD5Final

static u_int32 md_32(char *string, int length)
{
  MD_CTX context;
  union {
    char   c[16];
    u_int32 x[4];
  } digest;
  u_int32 r;
  int i;
  
  MDInit (&context);
  MDUpdate (&context, (unsigned char *)string, length);
  MDFinal ((unsigned char *)&digest, &context);
  /* XOR the four parts into one word */
  for (i = 0, r = 0; i < 3; i++) r ^= digest.x[i];
  return r;
} /* md_32 */



/*
* Return random unsigned 32-bit quantity.
*/
u_int32 random32(int type)
{
  struct {
    int     type;
    struct  timeval tv;
    clock_t cpu;
    pid_t   pid;
    u_long  hid;
    uid_t   uid;
    gid_t   gid;
    struct  utsname name;
  } s;

  gettimeofday(&s.tv, 0);
  s.type = type;
  s.cpu  = clock();
  s.pid  = getpid();
  s.hid  = gethostid();
  s.uid  = getuid();
  s.gid  = getgid();
  uname(&s.name);

  return md_32((char *)&s, sizeof(s));
} /* random32 */
