date and time created 94/03/31 08:50:52 by bostic
authorKeith Bostic <bostic@ucbvax.Berkeley.EDU>
Thu, 31 Mar 1994 23:50:52 +0000 (15:50 -0800)
committerKeith Bostic <bostic@ucbvax.Berkeley.EDU>
Thu, 31 Mar 1994 23:50:52 +0000 (15:50 -0800)
SCCS-vsn: games/random/random.c 8.1

usr/src/games/random/random.c [new file with mode: 0644]

diff --git a/usr/src/games/random/random.c b/usr/src/games/random/random.c
new file mode 100644 (file)
index 0000000..d0861f0
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 1994
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Guy Harris at Network Appliance Corp.
+ *
+ *
+ * %sccs.include.redist.c%
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1994\n\
+       The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)random.c   8.1 (Berkeley) %G%";
+#endif /* not lint */
+
+#include <sys/types.h>
+
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+
+void usage __P((void));
+
+int
+main(argc, argv)
+       int argc;
+       char *argv[];
+{
+       extern int optind;
+       time_t now;
+       double denom;
+       int ch, random_exit, selected, unbuffer_output;
+       char *ep;
+
+       random_exit = unbuffer_output = 0;
+       while ((ch = getopt(argc, argv, "er")) != EOF)
+               switch (ch) {
+               case 'e':
+                       random_exit = 1;
+                       break;
+               case 'r':
+                       unbuffer_output = 1;
+                       break;
+               default:
+               case '?':
+                       usage();
+                       /* NOTREACHED */
+               }
+
+       argc -= optind;
+       argv += optind;
+
+       switch (argc) {
+       case 0:
+               denom = 2;
+               break;
+       case 1:
+               errno = 0;
+               denom = strtod(*argv, &ep);
+               if (errno == ERANGE)
+                       err(1, "%s", *argv);
+               if (denom == 0 || *ep != '\0')
+                       errx(1, "denominator is not valid.");
+               break;
+       default:
+               usage(); 
+               /* NOTREACHED */
+       }
+
+       (void)time(&now);
+       srandom((u_int)(now + getpid()));
+
+       /* Compute a random exit status between 0 and denom - 1. */
+       if (random_exit)
+               return ((denom * random()) / LONG_MAX);
+
+       /*
+        * Act as a filter, randomly choosing lines of the standard input
+        * to write to the standard output.
+        */
+       if (unbuffer_output)
+               setbuf(stdout, NULL);
+       
+       /*
+        * Select whether to print the first line.  (Prime the pump.)
+        * We find a random number between 0 and denom - 1 and, if it's
+        * 0 (which has a 1 / denom chance of being true), we select the
+        * line.
+        */
+       selected = !((denom * random()) / LONG_MAX);
+       while ((ch = getchar()) != EOF) {
+               if (selected)
+                       (void)putchar(ch);
+               if (ch == '\n') {
+                       /* End of that line.  See if we got an error. */
+                       if (ferror(stdout))
+                               err(2, "stdout");
+
+                       /* Now see if the next line is to be printed. */
+                       selected = !((denom * random()) / LONG_MAX);
+               }
+       }
+       if (ferror(stdin))
+               err(2, "stdin");
+       exit (0);
+}
+
+void
+usage()
+{
+       (void)fprintf(stderr, "usage: random [-er] [divisor]\n");
+       exit(1);
+}