1: /* $Header: fortune.c,v 1.10 85/11/01 15:19:49 arnold Exp $ */
   2: 
   3: # include   <sys/types.h>
   4: # include   <stdio.h>
   5: # include   <sys/file.h>
   6: # include   "strfile.h"
   7: 
   8: # define    TRUE    1
   9: # define    FALSE   0
  10: # define    bool    short
  11: 
  12: # define    MINW    6       /* minimum wait if desired */
  13: # define    CPERS   20      /* # of chars for each sec */
  14: # define    SLEN    160     /* # of chars in short fortune */
  15: 
  16: # define    FORTFILE    "/usr/games/lib/fortunes.dat"
  17: 
  18: bool    Wflag       = FALSE,    /* wait desired after fortune */
  19:     Sflag       = FALSE,    /* short fortune desired */
  20:     Lflag       = FALSE,    /* long fortune desired */
  21:     Oflag       = FALSE,    /* offensive fortunes only */
  22:     Aflag       = FALSE;    /* any fortune allowed */
  23: 
  24: char    *Fortfile   = FORTFILE, /* fortune database */
  25:     *Usage[]    = {
  26:        "usage:  fortune [ - ] [ -wsloa ] [ file ]",
  27:        "	- - give this summary of usage",
  28:        "	w - have program wait after printing message in order",
  29:        "	    to give time to read",
  30:        "	s - short fortune only",
  31:        "	l - long fortune only",
  32:        "	o - offensive fortunes only",
  33:        "	a - any fortune",
  34:        "		Mail suggested fortunes to \"fortune\"",
  35:     NULL
  36:     };
  37: 
  38: long    Seekpts[2];         /* seek pointers to fortunes */
  39: 
  40: FILE    *Inf;               /* input file */
  41: 
  42: STRFILE Tbl;                /* input table */
  43: 
  44: time_t  time();
  45: 
  46: main(ac, av)
  47: int ac;
  48: char    *av[];
  49: {
  50:     register char   c;
  51:     register int    nchar = 0;
  52:     register int    i;
  53: 
  54:     getargs(ac, av);
  55:     if ((Inf = fopen(Fortfile, "r+")) == NULL) {
  56:         perror(Fortfile);
  57:         exit(-1);
  58:     }
  59:     fread((char *) &Tbl, sizeof Tbl, 1, Inf);   /* NOSTRICT */
  60:     if (Tbl.str_longlen <= SLEN && Lflag) {
  61:         puts("Sorry, no long strings in this file");
  62:         exit(0);
  63:     }
  64:     if (Tbl.str_shortlen > SLEN && Sflag) {
  65:         puts("Sorry, no short strings in this file");
  66:         exit(0);
  67:     }
  68: 
  69:     /*
  70: 	 * initialize the pointer to the first -o fortune if need be.
  71: 	 */
  72:     if (Tbl.str_delims[2] == 0)
  73:         Tbl.str_delims[2] = Tbl.str_delims[0];
  74: 
  75:     do {
  76:         getfort();
  77:     } while ((Sflag && !is_short()) || (Lflag && !is_long()));
  78: 
  79:     fseek(Inf, Seekpts[0], 0);
  80:     while (c = getc(Inf)) {
  81:         nchar++;
  82:         putchar(c);
  83:     }
  84:     fflush(stdout);
  85:     fseek(Inf, 0L, 0);
  86: #ifdef  LOCK_EX
  87:     /*
  88: 	 * if we can, we exclusive lock, but since it isn't very
  89: 	 * important, we just punt if we don't have easy locking
  90: 	 * available.
  91: 	 */
  92:     flock(fileno(Inf), LOCK_EX);
  93: #endif	LOCK_EX
  94:     fwrite(&Tbl, 1, sizeof Tbl, Inf);
  95: #ifdef  LOCK_EX
  96:     flock(fileno(Inf), LOCK_UN);
  97: #endif	LOCK_EX
  98:     if (Wflag)
  99:         sleep(max((int) nchar / CPERS, MINW));
 100:     exit(0);
 101: }
 102: 
 103: /*
 104:  * is_short:
 105:  *	Return TRUE if fortune is "short".
 106:  */
 107: is_short()
 108: {
 109:     register int    nchar;
 110: 
 111:     if (!(Tbl.str_flags & (STR_RANDOM | STR_ORDERED)))
 112:         return (Seekpts[1] - Seekpts[0] <= SLEN);
 113:     fseek(Inf, Seekpts[0], 0);
 114:     nchar = 0;
 115:     while (getc(Inf))
 116:         nchar++;
 117:     return (nchar <= SLEN);
 118: }
 119: 
 120: /*
 121:  * is_long:
 122:  *	Return TRUE if fortune is "long".
 123:  */
 124: is_long()
 125: {
 126:     register int    nchar;
 127: 
 128:     if (!(Tbl.str_flags & (STR_RANDOM | STR_ORDERED)))
 129:         return (Seekpts[1] - Seekpts[0] > SLEN);
 130:     fseek(Inf, Seekpts[0], 0);
 131:     nchar = 0;
 132:     while (getc(Inf))
 133:         nchar++;
 134:     return (nchar > SLEN);
 135: }
 136: 
 137: /*
 138:  *	This routine evaluates the arguments on the command line
 139:  */
 140: getargs(ac, av)
 141: register int    ac;
 142: register char   *av[];
 143: {
 144:     register int    i;
 145:     register char   *sp;
 146:     register int    j;
 147:     register short  bad = 0;
 148: 
 149:     for (i = 1; i < ac; i++)  {
 150:         if (av[i][0] != '-') {
 151:             setuid(getuid());
 152:             setgid(getgid());
 153:             Fortfile = av[i];
 154:         }
 155:         else if (av[i][1] == '\0') {
 156:             j = 0;
 157:             while (Usage[j] != NULL)
 158:                 puts(Usage[j++]);
 159:             exit(0);
 160:             /* NOTREACHED */
 161:         }
 162:         else
 163:             for (sp = &av[i][1]; *sp != '\0'; sp++)
 164:                 switch (*sp) {
 165:                   case 'w': /* give time to read */
 166:                     Wflag++;
 167:                     break;
 168:                   case 's': /* short ones only */
 169:                     Sflag++;
 170:                     break;
 171:                   case 'l': /* long ones only */
 172:                     Lflag++;
 173:                     break;
 174:                   case 'o': /* offensive ones only */
 175:                     Oflag++;
 176:                     break;
 177:                   case 'a': /* any fortune */
 178:                     Aflag++;
 179:                     /*
 180: 					 * initialize the random number
 181: 					 * generator; throw away the first
 182: 					 * few numbers to avoid any non-
 183: 					 * randomness in startup
 184: 					 */
 185:                     srnd(time(NULL) + getpid());
 186:                     for (j = 0; j < 20; j++)
 187:                         (void) rnd(100);
 188:                     break;
 189:                   default:
 190:                     printf("unknown flag: '%c'\n", *sp);
 191:                     bad++;
 192:                     break;
 193:                 }
 194:     }
 195:     if (bad) {
 196:         printf("use \"%s -\" to get usage\n", av[0]);
 197:         exit(-1);
 198:     }
 199: }
 200: 
 201: /*
 202:  * getfort:
 203:  *	Get the fortune data file's seek pointer for the next fortune.
 204:  */
 205: getfort()
 206: {
 207:     register int    fortune;
 208: 
 209:     /*
 210: 	 * Make sure all values are in range.
 211: 	 */
 212: 
 213:     if (Tbl.str_delims[1] >= Tbl.str_delims[0])
 214:         Tbl.str_delims[1] = 0;
 215:     if (Tbl.str_delims[2] >= Tbl.str_numstr)
 216:         Tbl.str_delims[2] = Tbl.str_delims[0];
 217: 
 218:     if (Aflag) {
 219:         if (rnd(Tbl.str_numstr) < Tbl.str_delims[0])
 220:             fortune = Tbl.str_delims[1]++;
 221:         else
 222:             fortune = Tbl.str_delims[2]++;
 223:     }
 224:     else if (Oflag)
 225:         fortune = Tbl.str_delims[2]++;
 226:     else
 227:         fortune = Tbl.str_delims[1]++;
 228: 
 229:     fseek(Inf, (long)(sizeof Seekpts[0]) * fortune + sizeof Tbl, 0);
 230:     fread((char *) Seekpts, (sizeof Seekpts[0]), 2, Inf);
 231: }
 232: 
 233: max(i, j)
 234: register int    i, j;
 235: {
 236:     return (i >= j ? i : j);
 237: }

Defined functions

getargs defined in line 140; used 1 times
  • in line 54
getfort defined in line 205; used 1 times
  • in line 76
is_long defined in line 124; used 1 times
  • in line 77
is_short defined in line 107; used 1 times
  • in line 77
main defined in line 46; never used
max defined in line 233; used 1 times
  • in line 99

Defined variables

Fortfile defined in line 24; used 3 times
Seekpts defined in line 38; used 10 times
Tbl defined in line 42; used 25 times

Defined macros

CPERS defined in line 13; used 1 times
  • in line 99
FALSE defined in line 9; used 5 times
FORTFILE defined in line 16; used 1 times
  • in line 24
MINW defined in line 12; used 1 times
  • in line 99
SLEN defined in line 14; used 6 times
TRUE defined in line 8; never used
bool defined in line 10; used 1 times
  • in line 18
Last modified: 1986-01-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3533
Valid CSS Valid XHTML 1.0 Strict