# 2.11BSD#431 - /usr/src/games/fortune/fortune.c

##### Functions

    getargs           X
    getfort           X
    is_long           X
    is_short          X
    main              X
    max               X

##### Variables

    Fortfile          X
    Seekpts           X
    Tbl               X

##### Macros

    CPERS             X
    FALSE             X
    FORTFILE          X
    MINW              X
    SLEN              X
    TRUE              X
    bool              X

       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

- in line 55-56(2), 153

Seekpts defined in line 38; used 10 times

- in line 79, 112-113(3), 129-130(3), 229-230(3)

Tbl defined in line 42; used 25 times

- in line 59-64(4), 72-73(3), 94(2), 111, 128, 213-229(14)

#### Defined macros

CPERS defined in line 13; used 1 times

- in line 99

FALSE defined in line 9; used 5 times

- in line 18-22(5)

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

- in line 60-64(2), 112-117(2), 129-134(2)

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: 1654 |