diff options
Diffstat (limited to 'appl/cmd/fortune.b')
| -rwxr-xr-x | appl/cmd/fortune.b | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/appl/cmd/fortune.b b/appl/cmd/fortune.b new file mode 100755 index 00000000..7368e992 --- /dev/null +++ b/appl/cmd/fortune.b @@ -0,0 +1,100 @@ +# +# 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(ix, 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); +} |
