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

1.1       root        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: }

unix.superglobalmegacorp.com

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