X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-utils.git;a=blobdiff_plain;f=scripts%2Frandom-word;fp=scripts%2Frandom-word;h=a7a27999fd9589cdeb025eb5e4c16bacd42e5ebe;hp=0000000000000000000000000000000000000000;hb=e7284b3f690305c0dca5d2c16b961da3c86bcf4f;hpb=7b0f6295075890c38af080b3f1aec5fd7139a2db diff --git a/scripts/random-word b/scripts/random-word new file mode 100755 index 0000000..a7a2799 --- /dev/null +++ b/scripts/random-word @@ -0,0 +1,69 @@ +#!/usr/bin/perl + +use IO::Handle; +use IO::File; +use POSIX; + +$want= 1; +$filename= "/usr/share/dict/words"; +@randfile= ("/dev/urandom", "/dev/random"); + +sub fail ($) { die "random-word: $_[0]\n"; } +open D, ">/dev/null" or fail("open /dev/null: $!"); + +while ($ARGV[0] =~ m/^\-/) { + $_= shift @ARGV; + if (m/^\-\-?$/) { + last; + } elsif (m/^\-n(\d+)$/) { + $want= $1; + } elsif (m/^\-f/ && length > 2) { + $filename= $'; + } elsif (m/^\-r/ && length > 2) { + @randfile= ($'); + } elsif (m/^\-D$/) { + open D, ">&STDERR" or fail("dup stderr for debug: $!"); + } else { + fail("unknown option \`$_'"); + } +} + +sub debug ($) { + print D "random-word: debug: $_[0]\n" + or fail("write debug: $!"); +} + +for $randfile (@randfile) { + $r= new IO::File "$randfile", 'r'; + debug("open $randfile ".($r ? "ok" : "failed $!")); + last if $r; + $!==&ENOENT or fail("cannot open $randfile: $!"); +} +$r or fail("could not open any random device: $!\n (tried @randfile)"); +$r->autoflush(0); + +$w= new IO::File $filename, 'r'; +$w or fail("cannot open $filename: $!"); +debug("open $filename ok"); +@words= <$w>; +$w->error and fail("cannot read $filename: $!"); +debug("read $filename ok"); + +while (@out < $want) { + $!=0; read $r,$rbytes,4; + length $rbytes==4 or fail("cannot read $randfile: $!"); + $wordno= unpack 'L',$rbytes; + $wordno &= ~0x80000000; + $wordno %= @words; + $_= $words[$wordno]; + chomp; + debug("picked $wordno \`$_'"); + next unless m/^([a-z][-a-z]+)$/; + push @out, $1; + debug("good, now ".scalar @out); +} + +debug("enough"); + +print join(' ',@out), "\n" + or fail("cannot write output: $!");