Skip site navigation (1)Skip section navigation (2)
Date:      Wed,  1 Dec 1999 13:28:13 +0100 (CET)
From:      dalroi@wit401310.student.utwente.nl
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   misc/15205: Addition to /usr/games/random
Message-ID:  <19991201122813.D48BA1EE3@wit401310.student.utwente.nl>

next in thread | raw e-mail | index | archive | help

>Number:         15205
>Category:       misc
>Synopsis:       Addition to /usr/games/random
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Wed Dec  1 05:40:02 PST 1999
>Closed-Date:
>Last-Modified:
>Originator:     Alban Hertroys
>Release:        FreeBSD 3.3-STABLE i386
>Organization:
>Environment:

	FreeBSD 3.3-STABLE, i386

>Description:

	The random command is not capable of what one would suspect it
	to do: printing one random line out of it's input.

	It can do so with numbers (random -e <denominator>), but not with lines
	of input.

>How-To-Repeat:

	not applicable

>Fix:
	
	The following patch adds the '-s' option to random, which prints one
	random line out of every <denominator> lines of input.

	Thus, "ls /bin | random -s 8" would result in, for example:
		chmod
		domainname
		pax
		stty

	(ls /bin results in 32 files on my system; 32/8 = 4 results)

	And "ls /bin | random -s $#" (invoked from a shell script) would result in one
	line from ls /bin.

	I use this for my random signature selector script. I suppose it has other
	uses.


diff -c games/random.orig/random.6 games/random/random.6
*** games/random.orig/random.6	Mon Nov 29 20:09:59 1999
--- games/random/random.6	Mon Nov 29 20:09:01 1999
***************
*** 39,45 ****
  .Nd random lines from a file or random numbers
  .Sh SYNOPSIS
  .Nm random
! .Op Fl er
  .Op Ar denominator
  .Sh DESCRIPTION
  .Nm Random
--- 39,45 ----
  .Nd random lines from a file or random numbers
  .Sh SYNOPSIS
  .Nm random
! .Op Fl esr
  .Op Ar denominator
  .Sh DESCRIPTION
  .Nm Random
***************
*** 60,65 ****
--- 60,73 ----
  exit value of 0 to
  .Ar denominator
  \&- 1, inclusive.
+ .It Fl s
+ If the
+ .Fl s
+ option is specified, 
+ .Nm random
+ copies one random line out of every 
+ .Ar denominator
+ lines to stdout, instead.
  .It Fl r
  The
  .Fl r
diff -c games/random.orig/random.c games/random/random.c
*** games/random.orig/random.c	Mon Nov 29 19:26:29 1999
--- games/random/random.c	Mon Nov 29 20:03:20 1999
***************
*** 63,73 ****
  {
  	extern int optind;
  	double denom;
! 	int ch, random_exit, selected, unbuffer_output;
  	char *ep;
  
! 	random_exit = unbuffer_output = 0;
! 	while ((ch = getopt(argc, argv, "er")) != -1)
  		switch (ch) {
  		case 'e':
  			random_exit = 1;
--- 63,73 ----
  {
  	extern int optind;
  	double denom;
! 	int ch, random_exit, selected, unbuffer_output, random_select, index;
  	char *ep;
  
! 	random_exit = unbuffer_output = random_select = 0;
! 	while ((ch = getopt(argc, argv, "esr")) != -1)
  		switch (ch) {
  		case 'e':
  			random_exit = 1;
***************
*** 75,80 ****
--- 75,83 ----
  		case 'r':
  			unbuffer_output = 1;
  			break;
+ 		case 's':
+ 			random_select = 1;
+ 			break;
  		default:
  		case '?':
  			usage();
***************
*** 116,138 ****
  	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 = (int)(denom * random() / LONG_MAX) == 0;
! 	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 = (int)(denom * random() / LONG_MAX) == 0;
  		}
  	}
  	if (ferror(stdin))
--- 119,164 ----
  	if (unbuffer_output)
  		setbuf(stdout, NULL);
  
+ 	if (random_select == 0) {
  	/*
  	 * 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 = (int)(denom * random() / LONG_MAX) == 0;
! 		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 = (int)(denom * random() / LONG_MAX) == 0;
! 			}
! 		}
! 	} else {
! 	/*
! 	 * Print one random line out of every denom lines.
! 	 */
! 		selected = (int)(denom * random() / LONG_MAX);
! 		index = 0;
! 		while ((ch = getchar()) != EOF) {
! 			if (selected == index)
! 				(void)putchar(ch);
! 			if (ch == '\n') {
! 				/* End of that line. See if we got an error. */
! 				if (ferror(stdout))
! 					err(2,"stdout");
! 
! 				index++;
! 				if (index >= denom) {
! 					index = 0;
! 					selected = (int)(denom * random() / LONG_MAX);
! 				}
! 			}
  		}
  	}
  	if (ferror(stdin))
***************
*** 144,149 ****
  usage()
  {
  
! 	(void)fprintf(stderr, "usage: random [-er] [denominator]\n");
  	exit(1);
  }
--- 170,175 ----
  usage()
  {
  
! 	(void)fprintf(stderr, "usage: random [-esr] [denominator]\n");
  	exit(1);
  }


>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19991201122813.D48BA1EE3>