1*66531Sbostic /* 2*66531Sbostic * Copyright (c) 1994 3*66531Sbostic * The Regents of the University of California. All rights reserved. 4*66531Sbostic * 5*66531Sbostic * This code is derived from software contributed to Berkeley by 6*66531Sbostic * Guy Harris at Network Appliance Corp. 7*66531Sbostic * 8*66531Sbostic * 9*66531Sbostic * %sccs.include.redist.c% 10*66531Sbostic */ 11*66531Sbostic 12*66531Sbostic #ifndef lint 13*66531Sbostic static char copyright[] = 14*66531Sbostic "@(#) Copyright (c) 1994\n\ 15*66531Sbostic The Regents of the University of California. All rights reserved.\n"; 16*66531Sbostic #endif /* not lint */ 17*66531Sbostic 18*66531Sbostic #ifndef lint 19*66531Sbostic static char sccsid[] = "@(#)random.c 8.1 (Berkeley) 03/31/94"; 20*66531Sbostic #endif /* not lint */ 21*66531Sbostic 22*66531Sbostic #include <sys/types.h> 23*66531Sbostic 24*66531Sbostic #include <err.h> 25*66531Sbostic #include <errno.h> 26*66531Sbostic #include <stdio.h> 27*66531Sbostic #include <stdlib.h> 28*66531Sbostic #include <time.h> 29*66531Sbostic #include <unistd.h> 30*66531Sbostic 31*66531Sbostic void usage __P((void)); 32*66531Sbostic 33*66531Sbostic int 34*66531Sbostic main(argc, argv) 35*66531Sbostic int argc; 36*66531Sbostic char *argv[]; 37*66531Sbostic { 38*66531Sbostic extern int optind; 39*66531Sbostic time_t now; 40*66531Sbostic double denom; 41*66531Sbostic int ch, random_exit, selected, unbuffer_output; 42*66531Sbostic char *ep; 43*66531Sbostic 44*66531Sbostic random_exit = unbuffer_output = 0; 45*66531Sbostic while ((ch = getopt(argc, argv, "er")) != EOF) 46*66531Sbostic switch (ch) { 47*66531Sbostic case 'e': 48*66531Sbostic random_exit = 1; 49*66531Sbostic break; 50*66531Sbostic case 'r': 51*66531Sbostic unbuffer_output = 1; 52*66531Sbostic break; 53*66531Sbostic default: 54*66531Sbostic case '?': 55*66531Sbostic usage(); 56*66531Sbostic /* NOTREACHED */ 57*66531Sbostic } 58*66531Sbostic 59*66531Sbostic argc -= optind; 60*66531Sbostic argv += optind; 61*66531Sbostic 62*66531Sbostic switch (argc) { 63*66531Sbostic case 0: 64*66531Sbostic denom = 2; 65*66531Sbostic break; 66*66531Sbostic case 1: 67*66531Sbostic errno = 0; 68*66531Sbostic denom = strtod(*argv, &ep); 69*66531Sbostic if (errno == ERANGE) 70*66531Sbostic err(1, "%s", *argv); 71*66531Sbostic if (denom == 0 || *ep != '\0') 72*66531Sbostic errx(1, "denominator is not valid."); 73*66531Sbostic break; 74*66531Sbostic default: 75*66531Sbostic usage(); 76*66531Sbostic /* NOTREACHED */ 77*66531Sbostic } 78*66531Sbostic 79*66531Sbostic (void)time(&now); 80*66531Sbostic srandom((u_int)(now + getpid())); 81*66531Sbostic 82*66531Sbostic /* Compute a random exit status between 0 and denom - 1. */ 83*66531Sbostic if (random_exit) 84*66531Sbostic return ((denom * random()) / LONG_MAX); 85*66531Sbostic 86*66531Sbostic /* 87*66531Sbostic * Act as a filter, randomly choosing lines of the standard input 88*66531Sbostic * to write to the standard output. 89*66531Sbostic */ 90*66531Sbostic if (unbuffer_output) 91*66531Sbostic setbuf(stdout, NULL); 92*66531Sbostic 93*66531Sbostic /* 94*66531Sbostic * Select whether to print the first line. (Prime the pump.) 95*66531Sbostic * We find a random number between 0 and denom - 1 and, if it's 96*66531Sbostic * 0 (which has a 1 / denom chance of being true), we select the 97*66531Sbostic * line. 98*66531Sbostic */ 99*66531Sbostic selected = !((denom * random()) / LONG_MAX); 100*66531Sbostic while ((ch = getchar()) != EOF) { 101*66531Sbostic if (selected) 102*66531Sbostic (void)putchar(ch); 103*66531Sbostic if (ch == '\n') { 104*66531Sbostic /* End of that line. See if we got an error. */ 105*66531Sbostic if (ferror(stdout)) 106*66531Sbostic err(2, "stdout"); 107*66531Sbostic 108*66531Sbostic /* Now see if the next line is to be printed. */ 109*66531Sbostic selected = !((denom * random()) / LONG_MAX); 110*66531Sbostic } 111*66531Sbostic } 112*66531Sbostic if (ferror(stdin)) 113*66531Sbostic err(2, "stdin"); 114*66531Sbostic exit (0); 115*66531Sbostic } 116*66531Sbostic 117*66531Sbostic void 118*66531Sbostic usage() 119*66531Sbostic { 120*66531Sbostic (void)fprintf(stderr, "usage: random [-er] [divisor]\n"); 121*66531Sbostic exit(1); 122*66531Sbostic } 123