home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / misc / cookie.lha / cookie.c < prev    next >
C/C++ Source or Header  |  1992-06-01  |  3KB  |  126 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 <math.h>
  7. #include <proto/exec.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <time.h>
  11. #include "cookie.h"
  12.  
  13. #define ENTSIZE 7L
  14. #define METACHAR '%'
  15. #define YES 1
  16. #define NO 0
  17.  
  18. char *sccs_id = "@(#) fortune cookie program 1.1 1/12/89 by K. Lehenbauer";
  19.  
  20. char *cookiename = COOKIEFILE;
  21. char *hashname = HASHFILE;
  22.  
  23. /* really_random - insure a good random return for a range, unlike an arbitrary
  24.  * random() % n, thanks to Ken Arnold, Unix Review, October 1987
  25.  * ...likely needs a little hacking to run under Berkely
  26.  */
  27. #define RANDOM_RANGE ((1 << 15) - 1)
  28. int really_random(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(int argc,char *argv[])
  40. {
  41.     int nentries, oneiwant, c, sawmeta = 0;
  42.     FILE *hashf, *cookief;
  43.     long cookiepos;
  44.  
  45.     /* if we got exactly three arguments, use the cookie and hash
  46.      * files specified
  47.      */
  48.     if (argc == 3)
  49.     {
  50.         cookiename = argv[1];
  51.         hashname = argv[2];
  52.     }
  53.     /* otherwise if argc isn't one (no arguments, specifying the
  54.      * default cookie file), barf
  55.      */
  56.     else if (argc != 1)
  57.     {
  58.         fputs("usage: cookie cookiefile hashfile\n",stderr);
  59.         exit(1);
  60.     }
  61.  
  62.     /* open the cookie file for read */
  63.     if ((cookief = fopen(cookiename,"r")) == NULL)
  64.     {
  65.         perror(cookiename);
  66.         exit(2);
  67.     }
  68.  
  69.     /* open the hash file for read */
  70.     if ((hashf = fopen(hashname,"r")) == NULL)
  71.     {
  72.         perror(hashname);
  73.         exit(2);
  74.     }
  75.  
  76.     /* compute number of cookie addresses in the hash file by
  77.      * dividing the file length by the size of a cookie address
  78.      */
  79.     if (fseek(hashf,0L,2) != 0)
  80.     {
  81.         perror(hashname);
  82.         exit(3);
  83.     }
  84.     nentries = ftell(hashf) / 7L;
  85.  
  86.     /* seed the random number generator with time in seconds plus
  87.      * the program's process ID - it yields a pretty good seed
  88.      * again, thanks to Ken Arnold
  89.      */
  90.     srand((long)FindTask(NULL) + time(NULL));
  91.  
  92.     /* generate a not really random number */
  93.     /* this was the original unix s5r4 version, too sophisticated
  94.        oneiwant = really_random(nentries); */
  95.     /* this is version seems to be random enough ;-) (AMK) */
  96.     oneiwant = rand() % nentries;
  97.  
  98.     /* locate the one I want in the hash file and read the
  99.      * address found there
  100.      */
  101.     fseek(hashf,(long)oneiwant * ENTSIZE, 0);
  102.     fscanf(hashf,"%lx",&cookiepos);
  103.  
  104.     /* seek cookie file to cookie starting at address read from hash */
  105.     fseek(cookief,cookiepos,0);
  106.  
  107.     /* get characters from the cookie file and write them out
  108.      * until finding the end-of-fortune sequence, '%%'
  109.      */
  110.     while ((c = fgetc(cookief)) != EOF && sawmeta < 2)
  111.     {
  112.         if (c != METACHAR)
  113.         {
  114.             if (sawmeta)
  115.                 putchar(METACHAR);
  116.             putchar(c);
  117.             sawmeta = 0;
  118.         }
  119.         else
  120.             sawmeta++;
  121.     }
  122.     exit(0);
  123. }
  124.  
  125. /* end of cookie.c */
  126.