fortune.c 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. char choice[2048];
  5. char index[] = "/sys/games/lib/fortunes.index";
  6. char fortunes[] = "/sys/games/lib/fortunes";
  7. void
  8. main(int argc, char *argv[])
  9. {
  10. int i;
  11. long offs;
  12. uchar off[4];
  13. int ix, nix;
  14. int newindex, oldindex;
  15. char *p;
  16. Dir *fbuf, *ixbuf;
  17. Biobuf *f, g;
  18. newindex = 0;
  19. oldindex = 0;
  20. ix = offs = 0;
  21. if((f=Bopen(argc>1?argv[1]:fortunes, OREAD)) == 0){
  22. print("Misfortune!\n");
  23. exits("misfortune");
  24. }
  25. ixbuf = nil;
  26. if(argc == 1){
  27. ix = open(index, OREAD);
  28. if(ix>=0){
  29. ixbuf = dirfstat(ix);
  30. fbuf = dirfstat(Bfildes(f));
  31. if(ixbuf == nil || fbuf == nil){
  32. print("Misfortune?\n");
  33. exits("misfortune");
  34. }
  35. if(ixbuf->length == 0){
  36. /* someone else is rewriting the index */
  37. goto NoIndex;
  38. }
  39. oldindex = 1;
  40. if(fbuf->mtime > ixbuf->mtime){
  41. nix = create(index, OWRITE, 0666);
  42. if(nix >= 0){
  43. close(ix);
  44. ix = nix;
  45. newindex = 1;
  46. oldindex = 0;
  47. }
  48. }
  49. }else{
  50. ix = create(index, OWRITE, 0666);
  51. if(ix >= 0)
  52. newindex = 1;
  53. }
  54. }
  55. if(oldindex){
  56. seek(ix, truerand()%(ixbuf->length/sizeof(offs))*sizeof(offs), 0);
  57. read(ix, off, sizeof(off));
  58. Bseek(f, off[0]|(off[1]<<8)|(off[2]<<16)|(off[3]<<24), 0);
  59. p = Brdline(f, '\n');
  60. if(p){
  61. p[Blinelen(f)-1] = 0;
  62. strcpy(choice, p);
  63. }else
  64. strcpy(choice, "Misfortune!");
  65. }else{
  66. NoIndex:
  67. Binit(&g, ix, 1);
  68. srand(truerand());
  69. for(i=1;;i++){
  70. if(newindex)
  71. offs = Boffset(f);
  72. p = Brdline(f, '\n');
  73. if(p == 0)
  74. break;
  75. p[Blinelen(f)-1] = 0;
  76. if(newindex){
  77. off[0] = offs;
  78. off[1] = offs>>8;
  79. off[2] = offs>>16;
  80. off[3] = offs>>24;
  81. Bwrite(&g, off, sizeof(off));
  82. }
  83. if(lrand()%i==0)
  84. strcpy(choice, p);
  85. }
  86. }
  87. print("%s\n", choice);
  88. exits(0);
  89. }