chiark / gitweb /
@@ -2,6 +2,7 @@
[chiark-utils.git] / scripts / random-word
1 #!/usr/bin/perl
2
3 use IO::Handle;
4 use IO::File;
5 use POSIX;
6
7 $want= 1;
8 $filename= "/usr/share/dict/words";
9 @randfile= ("/dev/urandom", "/dev/random");
10
11 sub fail ($) { die "random-word: $_[0]\n"; }
12 open D, ">/dev/null" or fail("open /dev/null: $!");
13
14 while ($ARGV[0] =~ m/^\-/) {
15     $_= shift @ARGV;
16     if (m/^\-\-?$/) {
17         last;
18     } elsif (m/^\-n(\d+)$/) {
19         $want= $1;
20     } elsif (m/^\-f/ && length > 2) {
21         $filename= $';
22     } elsif (m/^\-r/ && length > 2) {
23         @randfile= ($');
24     } elsif (m/^\-D$/) {
25         open D, ">&STDERR" or fail("dup stderr for debug: $!");
26     } else {
27         fail("unknown option \`$_'");
28     }
29 }
30
31 sub debug ($) {
32     print D "random-word: debug: $_[0]\n"
33         or fail("write debug: $!");
34 }
35
36 for $randfile (@randfile) {
37     $r= new IO::File "$randfile", 'r';
38     debug("open $randfile ".($r ? "ok" : "failed $!"));
39     last if $r;
40     $!==&ENOENT or fail("cannot open $randfile: $!");
41 }
42 $r or fail("could not open any random device: $!\n (tried @randfile)");
43 $r->autoflush(0);
44
45 $w= new IO::File $filename, 'r';
46 $w or fail("cannot open $filename: $!");
47 debug("open $filename ok");
48 @words= <$w>;
49 $w->error and fail("cannot read $filename: $!");
50 debug("read $filename ok");
51
52 while (@out < $want) {
53     $!=0; read $r,$rbytes,4;
54     length $rbytes==4 or fail("cannot read $randfile: $!");
55     $wordno= unpack 'L',$rbytes;
56     $wordno &= ~0x80000000;
57     $wordno %= @words;
58     $_= $words[$wordno];
59     chomp;
60     debug("picked $wordno \`$_'");
61     next unless m/^([a-z][-a-z]+)$/;
62     push @out, $1;
63     debug("good, now ".scalar @out);
64 }
65
66 debug("enough");
67
68 print join(' ',@out), "\n"
69     or fail("cannot write output: $!");