| #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); |
| } |