1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 5 char choice[2048]; 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, nix; 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 ixbuf = nil; 29 if(argc == 1){ 30 ix = open(index, OREAD); 31 if(ix>=0){ 32 ixbuf = dirfstat(ix); 33 fbuf = dirfstat(Bfildes(f)); 34 if(ixbuf == nil || fbuf == nil){ 35 print("Misfortune?\n"); 36 exits("misfortune"); 37 } 38 if(ixbuf->length == 0){ 39 /* someone else is rewriting the index */ 40 goto NoIndex; 41 } 42 oldindex = 1; 43 if(fbuf->mtime > ixbuf->mtime){ 44 nix = create(index, OWRITE, 0666); 45 if(nix >= 0){ 46 close(ix); 47 ix = nix; 48 newindex = 1; 49 oldindex = 0; 50 } 51 } 52 }else{ 53 ix = create(index, OWRITE, 0666); 54 if(ix >= 0) 55 newindex = 1; 56 } 57 } 58 if(oldindex){ 59 seek(ix, truerand()%(ixbuf->length/sizeof(offs))*sizeof(offs), 0); 60 read(ix, off, sizeof(off)); 61 Bseek(f, off[0]|(off[1]<<8)|(off[2]<<16)|(off[3]<<24), 0); 62 p = Brdline(f, '\n'); 63 if(p){ 64 p[Blinelen(f)-1] = 0; 65 strcpy(choice, p); 66 }else 67 strcpy(choice, "Misfortune!"); 68 }else{ 69 NoIndex: 70 Binit(&g, ix, 1); 71 srand(truerand()); 72 for(i=1;;i++){ 73 if(newindex) 74 offs = Boffset(f); 75 p = Brdline(f, '\n'); 76 if(p == 0) 77 break; 78 p[Blinelen(f)-1] = 0; 79 if(newindex){ 80 off[0] = offs; 81 off[1] = offs>>8; 82 off[2] = offs>>16; 83 off[3] = offs>>24; 84 Bwrite(&g, off, sizeof(off)); 85 } 86 if(lrand()%i==0) 87 strcpy(choice, p); 88 } 89 } 90 print("%s\n", choice); 91 exits(0); 92 } 93