xref: /plan9-contrib/sys/src/cmd/fortune.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 
5 char choice[512];
6 char index[] = "/sys/games/lib/fortunes.index";
7 char fortunes[] = "/sys/games/lib/fortunes";
8 
9 void
10 main(int argc, char *argv[])
11 {
12 	int i;
13 	long offs;
14 	uchar off[4];
15 	int ix;
16 	int newindex, oldindex;
17 	char *p;
18 	Dir fbuf, ixbuf;
19 	Biobuf *f, g;
20 
21 	newindex = 0;
22 	oldindex = 0;
23 	ix = offs = 0;
24 	if((f=Bopen(argc>1?argv[1]:fortunes, OREAD)) == 0){
25 		print("Misfortune!\n");
26 		exits("misfortune");
27 	}
28 	if(argc == 1){
29 		ix = open(index, OREAD);
30 		if(ix>=0){
31 			oldindex = 1;
32 			dirfstat(ix, &ixbuf);
33 			dirfstat(Bfildes(f), &fbuf);
34 			if(fbuf.mtime > ixbuf.mtime){
35 				close(ix);
36 				ix = create(index, OWRITE, 0666);
37 				if(ix >= 0){
38 					newindex = 1;
39 					oldindex = 0;
40 				}
41 			}
42 		}else{
43 			ix = create(index, OWRITE, 0666);
44 			if(ix >= 0)
45 				newindex = 1;
46 		}
47 	}
48 	srand(time(0));
49 	i = getpid()&32767;
50 	while(--i >= 0)
51 		rand();
52 	if(oldindex){
53 		seek(ix, nrand(ixbuf.length/sizeof(offs))*sizeof(offs), 0);
54 		read(ix, off, sizeof(off));
55 		Bseek(f, off[0]|(off[1]<<8)|(off[2]<<16)|(off[3]<<24), 0);
56 		p = Brdline(f, '\n');
57 		if(p){
58 			p[Blinelen(f)-1] = 0;
59 			strcpy(choice, p);
60 		}else
61 			strcpy(choice, "Misfortune!");
62 	}else{
63 		Binit(&g, ix, 1);
64 		for(i=1;;i++){
65 			if(newindex)
66 				offs = Boffset(f);
67 			p = Brdline(f, '\n');
68 			if(p == 0)
69 				break;
70 			p[Blinelen(f)-1] = 0;
71 			if(newindex){
72 				off[0] = offs;
73 				off[1] = offs>>8;
74 				off[2] = offs>>16;
75 				off[3] = offs>>24;
76 				Bwrite(&g, off, sizeof(off));
77 			}
78 			if(nrand(i)==0)
79 				strcpy(choice, p);
80 		}
81 	}
82 	print("%s\n", choice);
83 	exits(0);
84 }
85