# # 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); }