summaryrefslogtreecommitdiffstats
path: root/games
diff options
context:
space:
mode:
authormpp <mpp@FreeBSD.org>1997-02-23 23:03:47 +0000
committermpp <mpp@FreeBSD.org>1997-02-23 23:03:47 +0000
commit67b46541d30ffb47c00ac6af9fa56172f021bab4 (patch)
tree5dff4ed039166a30e5899714e8f809d97deccd40 /games
parent76a899ae26f03a113631b33475e6d64fbe925b55 (diff)
downloadFreeBSD-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.c43
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.
*/
OpenPOWER on IntegriCloud