Annotation of 43BSDTahoe/games/fortune/fortune.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.