ref: ad7316e87cd0444908caa74a5dfd4cf6168c5472
dir: /sys/src/cmd/fortune.c/
#include <u.h> #include <libc.h> #include <bio.h> char choice[2048]; char index[] = "/sys/games/lib/fortunes.index"; char fortunes[] = "/sys/games/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; 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){ ixbuf = dirfstat(ix); fbuf = dirfstat(Bfildes(f)); if(ixbuf == nil || fbuf == nil){ print("Misfortune?\n"); exits("misfortune"); } if(ixbuf->length < sizeof(offs)){ /* someone else is rewriting the index */ goto NoIndex; } oldindex = 1; 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){ seek(ix, ntruerand(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; strncpy(choice, p, sizeof(choice)-1); }else strcpy(choice, "Misfortune!"); }else{ NoIndex: Binit(&g, ix, 1); srand(truerand()); 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(nrand(i)==0) strncpy(choice, p, sizeof(choice)-1); } } print("%s\n", choice); exits(0); }