diff options
author | mpp <mpp@FreeBSD.org> | 1997-02-23 23:03:47 +0000 |
---|---|---|
committer | mpp <mpp@FreeBSD.org> | 1997-02-23 23:03:47 +0000 |
commit | 67b46541d30ffb47c00ac6af9fa56172f021bab4 (patch) | |
tree | 5dff4ed039166a30e5899714e8f809d97deccd40 /games | |
parent | 76a899ae26f03a113631b33475e6d64fbe925b55 (diff) | |
download | FreeBSD-src-67b46541d30ffb47c00ac6af9fa56172f021bab4.zip FreeBSD-src-67b46541d30ffb47c00ac6af9fa56172f021bab4.tar.gz |
Allow fortune to use /dev/urandom if available to obtain its random
numbers. If /dev/urandom is unavailable, it will fall back to
using the random() function.
I did this because I'm sick of seeing the same handful of fortunes
over and over, and I've seen the exact same fortune one too many times
when starting up two login shells at the same time.
2.2 safe.
Diffstat (limited to 'games')
-rw-r--r-- | games/fortune/fortune/fortune.c | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/games/fortune/fortune/fortune.c b/games/fortune/fortune/fortune.c index e993a1b..5853bbf 100644 --- a/games/fortune/fortune/fortune.c +++ b/games/fortune/fortune/fortune.c @@ -135,6 +135,7 @@ int form_file_list __P((char **, int)); int fortlen __P((void)); void get_fort __P((void)); void get_pos __P((FILEDESC *)); +long get_random __P((void)); void get_tbl __P((FILEDESC *)); void getargs __P((int, char *[])); void init_prob __P((void)); @@ -952,7 +953,7 @@ get_fort() if (File_list->next == NULL || File_list->percent == NO_PROB) fp = File_list; else { - choice = random() % 100; + choice = get_random() % 100; DPRINTF(1, (stderr, "choice = %d\n", choice)); for (fp = File_list; fp->percent != NO_PROB; fp = fp->next) if (choice < fp->percent) @@ -972,7 +973,7 @@ get_fort() else { if (fp->next != NULL) { sum_noprobs(fp); - choice = random() % Noprob_tbl.str_numstr; + choice = get_random() % Noprob_tbl.str_numstr; DPRINTF(1, (stderr, "choice = %d (of %ld) \n", choice, Noprob_tbl.str_numstr)); while (choice >= fp->tbl.str_numstr) { @@ -1014,7 +1015,7 @@ FILEDESC *parent; register int choice; if (Equal_probs) { - choice = random() % parent->num_children; + choice = get_random() % parent->num_children; DPRINTF(1, (stderr, " choice = %d (of %d)\n", choice, parent->num_children)); for (fp = parent->child; choice--; fp = fp->next) @@ -1024,7 +1025,7 @@ FILEDESC *parent; } else { get_tbl(parent); - choice = random() % parent->tbl.str_numstr; + choice = get_random() % parent->tbl.str_numstr; DPRINTF(1, (stderr, " choice = %d (of %ld)\n", choice, parent->tbl.str_numstr)); for (fp = parent->child; choice >= fp->tbl.str_numstr; @@ -1113,13 +1114,13 @@ FILEDESC *fp; #ifdef OK_TO_WRITE_DISK if ((fd = open(fp->posfile, 0)) < 0 || read(fd, &fp->pos, sizeof fp->pos) != sizeof fp->pos) - fp->pos = random() % fp->tbl.str_numstr; + fp->pos = get_random() % fp->tbl.str_numstr; else if (fp->pos >= fp->tbl.str_numstr) fp->pos %= fp->tbl.str_numstr; if (fd >= 0) (void) close(fd); #else - fp->pos = random() % fp->tbl.str_numstr; + fp->pos = get_random() % fp->tbl.str_numstr; #endif /* OK_TO_WRITE_DISK */ } if (++(fp->pos) >= fp->tbl.str_numstr) @@ -1128,6 +1129,36 @@ FILEDESC *fp; } /* + * get_random: + * Get a random number, either via /dev/urandom, or random() + * if /dev/urandom is not available. + */ +long +get_random() +{ + static int how = 0; + int fd; + long rnd; + + if (how == 0) { + if ((fd = open("/dev/urandom", O_RDONLY)) >= 0) + how = 1; + else + how = 2; + } + if (how == 1) { + if (read(fd, (void *) &rnd, sizeof(rnd)) < 0) { + how = 2; + } + else { + rnd = abs(rnd); + return (rnd); + } + } + return (random()); +} + +/* * get_tbl: * Get the tbl data file the datfile. */ |