fortune.c (1748B)
1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 5 #define index findex 6 char choice[2048]; 7 char *index = "#9/lib/fortunes.index"; 8 char *fortunes = "#9/lib/fortunes"; 9 10 void 11 main(int argc, char *argv[]) 12 { 13 int i; 14 long offs; 15 uchar off[4]; 16 int ix, nix; 17 int newindex, oldindex; 18 char *p; 19 Dir *fbuf, *ixbuf; 20 Biobuf *f, g; 21 22 index = unsharp(index); 23 fortunes = unsharp(fortunes); 24 25 newindex = 0; 26 oldindex = 0; 27 ix = offs = 0; 28 if((f=Bopen(argc>1?argv[1]:fortunes, OREAD)) == 0){ 29 print("Misfortune!\n"); 30 exits("misfortune"); 31 } 32 ixbuf = nil; 33 if(argc == 1){ 34 ix = open(index, OREAD); 35 if(ix>=0){ 36 oldindex = 1; 37 ixbuf = dirfstat(ix); 38 fbuf = dirfstat(Bfildes(f)); 39 if(ixbuf == nil || fbuf == nil){ 40 print("Misfortune?\n"); 41 exits("misfortune"); 42 } 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 srand(getpid()); 60 seek(ix, lrand()%(ixbuf->length/sizeof(offs))*sizeof(offs), 0); 61 read(ix, off, sizeof(off)); 62 Bseek(f, off[0]|(off[1]<<8)|(off[2]<<16)|(off[3]<<24), 0); 63 p = Brdline(f, '\n'); 64 if(p){ 65 p[Blinelen(f)-1] = 0; 66 strcpy(choice, p); 67 }else 68 strcpy(choice, "Misfortune!"); 69 }else{ 70 Binit(&g, ix, 1); 71 srand(getpid()); 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 }