1# 2# initially generated by c2l 3# 4 5implement Fortune; 6 7Fortune: module 8{ 9 init: fn(nil: ref Draw->Context, argl: list of string); 10}; 11 12include "sys.m"; 13 sys: Sys; 14 Dir: import sys; 15 16include "draw.m"; 17 18include "bufio.m"; 19 bufio: Bufio; 20 Iobuf: import bufio; 21 22include "rand.m"; 23 rand: Rand; 24 25include "keyring.m"; 26include "security.m"; 27 28choice: string; 29findex := "/lib/games/fortunes.index"; 30fortunes := "/lib/games/fortunes"; 31 32init(nil: ref Draw->Context, args: list of string) 33{ 34 sys = load Sys Sys->PATH; 35 bufio = load Bufio Bufio->PATH; 36 rand = load Rand Rand->PATH; 37 38 if(args != nil) 39 args = tl args; 40 if(args != nil) 41 filename := hd args; 42 else 43 filename = fortunes; 44 if((f := bufio->open(filename, Bufio->OREAD)) == nil){ 45 sys->fprint(sys->fildes(2), "fortune: can't open %s: %r\n", filename); 46 raise "fail:open"; 47 } 48 ix, nix: ref Sys->FD; 49 length := big 0; 50 if(args == nil){ 51 ix = sys->open(findex, Sys->OREAD); 52 if(ix != nil){ 53 (nil, ixbuf) := sys->fstat(ix); 54 (nil, fbuf) := sys->fstat(f.fd); 55 if(fbuf.mtime >= ixbuf.mtime){ 56 ix = nil; 57 nix = sys->create(findex, Sys->OWRITE, 8r666); 58 }else 59 length = ixbuf.length; 60 }else 61 nix = sys->create(findex, Sys->OWRITE, 8r666); 62 } 63 off := array[4] of byte; 64 if(ix != nil && length != big 0){ 65 sys->seek(ix, ((big truerand() & ((big 1<<32)-big 1))%length) & ~big 3, 0); 66 sys->read(ix, off, 4); 67 f.seek(big (int off[0]|int off[1]<<8|int off[2]<<16|int off[3]<<24), 0); 68 choice = f.gets('\n'); 69 if(choice == nil) 70 choice = "Misfortune!\n"; 71 }else{ 72 rand->init(truerand()); 73 offs := 0; 74 g := bufio->fopen(nix, Bufio->ORDWR); 75 for(i := 1;; i++){ 76 if(nix != nil) 77 offs = int f.offset(); 78 p := f.gets('\n'); 79 if(p == nil) 80 break; 81 if(nix != nil){ 82 off[0] = byte offs; 83 off[1] = byte (offs>>8); 84 off[2] = byte (offs>>16); 85 off[3] = byte (offs>>24); 86 g.write(off, 4); 87 } 88 if(rand->rand(i) == 0) 89 choice = p; 90 } 91 g.flush(); 92 } 93 sys->print("%s", choice); 94} 95 96truerand(): int 97{ 98 random := load Random Random->PATH; 99 return random->randomint(Random->ReallyRandom); 100} 101