summaryrefslogtreecommitdiff
path: root/appl/cmd/fortune.b
diff options
context:
space:
mode:
Diffstat (limited to 'appl/cmd/fortune.b')
-rwxr-xr-xappl/cmd/fortune.b100
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);
+}