xref: /inferno-os/appl/cmd/fortune.b (revision 6e425a9de8c003b5a733621a6b6730ec3cc902b8)
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