home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1976 / cookie.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-28  |  2.6 KB  |  125 lines

  1. /* cookie - print out an entry from the sayings file
  2.  * by Karl Lehenbauer (karl@sugar.uu.net, uunet!sugar!karl)
  3.  *  cookie.c  1.1  1/12/89
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include "cookie.h"
  8.  
  9. #define ENTSIZE 7L
  10. #define METACHAR '%'
  11. #define YES 1
  12. #define NO 0
  13.  
  14. char *sccs_id = "@(#) fortune cookie program 1.1 1/12/89 by K. Lehenbauer";
  15.  
  16. extern long lseek(), time();
  17. extern int rand();
  18.  
  19. char *cookiename = COOKIEFILE;
  20. char *hashname = HASHFILE;
  21.  
  22. /* really_random - insure a good random return for a range, unlike an arbitrary
  23.  * random() % n, thanks to Ken Arnold, Unix Review, October 1987
  24.  * ...likely needs a little hacking to run under Berkely
  25.  */
  26. #define RANDOM_RANGE ((1 << 15) - 1)
  27. int really_random(my_range)
  28. int my_range;
  29. {
  30.     int max_multiple, rnum;
  31.  
  32.     max_multiple = RANDOM_RANGE / my_range;
  33.     max_multiple *= my_range;
  34.     while ((rnum = rand()) >= max_multiple)
  35.         continue;
  36.     return(rnum % my_range);
  37. }
  38.  
  39. main(argc,argv)
  40. int argc;
  41. char *argv[];
  42. {
  43.     int nentries, oneiwant, c, sawmeta = 0;
  44.     FILE *hashf, *cookief;
  45.     long cookiepos;
  46.  
  47.     /* if we got exactly three arguments, use the cookie and hash
  48.      * files specified
  49.      */
  50.     if (argc == 3)
  51.     {
  52.         cookiename = argv[1];
  53.         hashname = argv[2];
  54.     }
  55.     /* otherwise if argc isn't one (no arguments, specifying the
  56.      * default cookie file), barf
  57.      */
  58.     else if (argc != 1)
  59.     {
  60.         fputs("usage: cookie cookiefile hashfile\n",stderr);
  61.         exit(1);
  62.     }
  63.  
  64.     /* open the cookie file for read */
  65.     if ((cookief = fopen(cookiename,"r")) == NULL)
  66.     {
  67.         perror(cookiename);
  68.         exit(2);
  69.     }
  70.  
  71.     /* open the hash file for read */
  72.     if ((hashf = fopen(hashname,"r")) == NULL)
  73.     {
  74.         perror(hashname);
  75.         exit(2);
  76.     }
  77.  
  78.     /* compute number of cookie addresses in the hash file by
  79.      * dividing the file length by the size of a cookie address
  80.      */
  81.     if (fseek(hashf,0L,2) != 0)
  82.     {
  83.         perror(hashname);
  84.         exit(3);
  85.     }
  86.     nentries = ftell(hashf) / 7L;
  87.  
  88.     /* seed the random number generator with time in seconds plus
  89.      * the program's process ID - it yields a pretty good seed
  90.      * again, thanks to Ken Arnold
  91.      */
  92.     srand(getpid() + time(NULL));
  93.  
  94.     /* generate a not really random number */
  95.     oneiwant = really_random(nentries);
  96.  
  97.     /* locate the one I want in the hash file and read the
  98.      * address found there
  99.      */
  100.     fseek(hashf,(long)oneiwant * ENTSIZE, 0);
  101.     fscanf(hashf,"%lx",&cookiepos);
  102.  
  103.     /* seek cookie file to cookie starting at address read from hash */
  104.     fseek(cookief,cookiepos,0);
  105.  
  106.     /* get characters from the cookie file and write them out
  107.      * until finding the end-of-fortune sequence, '%%'
  108.      */
  109.     while ((c = fgetc(cookief)) != EOF && sawmeta < 2)
  110.     {
  111.         if (c != METACHAR)
  112.         {
  113.             if (sawmeta)
  114.                 putchar(METACHAR);
  115.             putchar(c);
  116.             sawmeta = 0;
  117.         }
  118.         else
  119.             sawmeta++;
  120.     }
  121.     exit(0);
  122. }
  123.  
  124. /* end of cookie.c */
  125.