|  | #include <u.h> | 
|  | #include <libc.h> | 
|  | #include <bio.h> | 
|  |  | 
|  | #define index findex | 
|  | char choice[2048]; | 
|  | char *index = "#9/lib/fortunes.index"; | 
|  | char *fortunes = "#9/lib/fortunes"; | 
|  |  | 
|  | void | 
|  | main(int argc, char *argv[]) | 
|  | { | 
|  | int i; | 
|  | long offs; | 
|  | uchar off[4]; | 
|  | int ix, nix; | 
|  | int newindex, oldindex; | 
|  | char *p; | 
|  | Dir *fbuf, *ixbuf; | 
|  | Biobuf *f, g; | 
|  |  | 
|  | index = unsharp(index); | 
|  | fortunes = unsharp(fortunes); | 
|  |  | 
|  | newindex = 0; | 
|  | oldindex = 0; | 
|  | ix = offs = 0; | 
|  | if((f=Bopen(argc>1?argv[1]:fortunes, OREAD)) == 0){ | 
|  | print("Misfortune!\n"); | 
|  | exits("misfortune"); | 
|  | } | 
|  | ixbuf = nil; | 
|  | if(argc == 1){ | 
|  | ix = open(index, OREAD); | 
|  | if(ix>=0){ | 
|  | oldindex = 1; | 
|  | ixbuf = dirfstat(ix); | 
|  | fbuf = dirfstat(Bfildes(f)); | 
|  | if(ixbuf == nil || fbuf == nil){ | 
|  | print("Misfortune?\n"); | 
|  | exits("misfortune"); | 
|  | } | 
|  | if(fbuf->mtime > ixbuf->mtime){ | 
|  | nix = create(index, OWRITE, 0666); | 
|  | if(nix >= 0){ | 
|  | close(ix); | 
|  | ix = nix; | 
|  | newindex = 1; | 
|  | oldindex = 0; | 
|  | } | 
|  | } | 
|  | }else{ | 
|  | ix = create(index, OWRITE, 0666); | 
|  | if(ix >= 0) | 
|  | newindex = 1; | 
|  | } | 
|  | } | 
|  | if(oldindex){ | 
|  | srand(getpid()); | 
|  | seek(ix, lrand()%(ixbuf->length/sizeof(offs))*sizeof(offs), 0); | 
|  | read(ix, off, sizeof(off)); | 
|  | Bseek(f, off[0]|(off[1]<<8)|(off[2]<<16)|(off[3]<<24), 0); | 
|  | p = Brdline(f, '\n'); | 
|  | if(p){ | 
|  | p[Blinelen(f)-1] = 0; | 
|  | strcpy(choice, p); | 
|  | }else | 
|  | strcpy(choice, "Misfortune!"); | 
|  | }else{ | 
|  | Binit(&g, ix, 1); | 
|  | srand(getpid()); | 
|  | for(i=1;;i++){ | 
|  | if(newindex) | 
|  | offs = Boffset(f); | 
|  | p = Brdline(f, '\n'); | 
|  | if(p == 0) | 
|  | break; | 
|  | p[Blinelen(f)-1] = 0; | 
|  | if(newindex){ | 
|  | off[0] = offs; | 
|  | off[1] = offs>>8; | 
|  | off[2] = offs>>16; | 
|  | off[3] = offs>>24; | 
|  | Bwrite(&g, off, sizeof(off)); | 
|  | } | 
|  | if(lrand()%i==0) | 
|  | strcpy(choice, p); | 
|  | } | 
|  | } | 
|  | print("%s\n", choice); | 
|  | exits(0); | 
|  | } |