ref: babf901b4a508c3ec5d1f89655f10377bbdf9637
dir: /appl/cmd/fortune.b/
#
# initially generated by c2l
#
implement Fortune;
Fortune: module
{
init: fn(nil: ref Draw->Context, argl: list of string);
};
include "sys.m";
sys: Sys;
Dir: import sys;
include "draw.m";
include "bufio.m";
bufio: Bufio;
Iobuf: import bufio;
include "rand.m";
rand: Rand;
include "keyring.m";
include "security.m";
choice: string;
findex := "/lib/games/fortunes.index";
fortunes := "/lib/games/fortunes";
init(nil: ref Draw->Context, args: list of string)
{
sys = load Sys Sys->PATH;
bufio = load Bufio Bufio->PATH;
rand = load Rand Rand->PATH;
if(args != nil)
args = tl args;
if(args != nil)
filename := hd args;
else
filename = fortunes;
if((f := bufio->open(filename, Bufio->OREAD)) == nil){
sys->fprint(sys->fildes(2), "fortune: can't open %s: %r\n", filename);
raise "fail:open";
}
ix, nix: ref Sys->FD;
length := big 0;
if(args == nil){
ix = sys->open(findex, Sys->OREAD);
if(ix != nil){
(nil, ixbuf) := sys->fstat(ix);
(nil, fbuf) := sys->fstat(f.fd);
if(fbuf.mtime >= ixbuf.mtime){
ix = nil;
nix = sys->create(findex, Sys->OWRITE, 8r666);
}else
length = ixbuf.length;
}else
nix = sys->create(findex, Sys->OWRITE, 8r666);
}
off := array[4] of byte;
if(ix != nil && length != big 0){
sys->seek(ix, ((big truerand() & ((big 1<<32)-big 1))%length) & ~big 3, 0);
sys->read(ix, off, 4);
f.seek(big (int off[0]|int off[1]<<8|int off[2]<<16|int off[3]<<24), 0);
choice = f.gets('\n');
if(choice == nil)
choice = "Misfortune!\n";
}else{
rand->init(truerand());
offs := 0;
g := bufio->fopen(nix, Bufio->ORDWR);
for(i := 1;; i++){
if(nix != nil)
offs = int f.offset();
p := f.gets('\n');
if(p == nil)
break;
if(nix != nil){
off[0] = byte offs;
off[1] = byte (offs>>8);
off[2] = byte (offs>>16);
off[3] = byte (offs>>24);
g.write(off, 4);
}
if(rand->rand(i) == 0)
choice = p;
}
g.flush();
}
sys->print("%s", choice);
}
truerand(): int
{
random := load Random Random->PATH;
return random->randomint(Random->ReallyRandom);
}