|
|
1.1 ! root 1: #ifdef UCB_SCCSID ! 2: char *sccsid = "@(#)fortune.c 2.6"; ! 3: #endif ! 4: # include <stdio.h> ! 5: # include "strfile.h" ! 6: ! 7: # define MINW 6 /* minimum wait if desired */ ! 8: # define CPERS 20 /* # of chars for each sec */ ! 9: # define SLEN 160 /* # of chars in short fortune */ ! 10: ! 11: # define reg register ! 12: ! 13: short wflag = 0, /* wait desired after fortune */ ! 14: sflag = 0, /* short fortune desired */ ! 15: lflag = 0, /* long fortune desired */ ! 16: oflag = 0, /* offensive fortunes only */ ! 17: aflag = 0; /* any fortune allowed */ ! 18: ! 19: char fortfile[100] = FORTFILE, /* fortune database */ ! 20: *usage[] = { ! 21: "usage: fortune [ - ] [ -wsloa ] [ file ]", ! 22: " - - give this summary of usage", ! 23: " w - have program wait after printing message in order", ! 24: " to give time to read", ! 25: " s - short fortune only", ! 26: " l - long fortune only", ! 27: " o - offensive fortunes only", ! 28: " a - any fortune", ! 29: " Mail suggested fortunes to \"fortune\"" ! 30: }; ! 31: ! 32: long seekpts[2]; /* seek pointers to fortunes */ ! 33: ! 34: main(ac, av) ! 35: int ac; ! 36: char *av[]; { ! 37: ! 38: reg char c; ! 39: reg int nchar = 0; ! 40: reg FILE *inf; ! 41: int numforts, /* number of fortunes */ ! 42: fortune; /* fortune number */ ! 43: STRFILE tbl; /* input table */ ! 44: ! 45: getargs(ac, av); ! 46: srand(getpid()); ! 47: if ((inf = fopen(fortfile, "r")) == NULL) { ! 48: perror(fortfile); ! 49: exit(-1); ! 50: } ! 51: fread(&tbl, (sizeof tbl), 1, inf); ! 52: numforts = tbl.str_numstr - 1; /* always a null string at the end */ ! 53: if (tbl.str_longlen < SLEN && lflag) { ! 54: puts("Sorry, no long strings in this file"); ! 55: exit(0); ! 56: } ! 57: if (tbl.str_shortlen > SLEN && sflag) { ! 58: puts("Sorry, no short strings in this file"); ! 59: exit(0); ! 60: } ! 61: if (oflag) ! 62: numforts -= tbl.str_delims[0]; ! 63: else if (!aflag) ! 64: numforts = tbl.str_delims[0]; ! 65: do { ! 66: fortune = roll(1, numforts) - 1; ! 67: if (oflag && !aflag) ! 68: fortune += tbl.str_delims[0]; ! 69: fseek(inf, (long)(sizeof seekpts[0]) * fortune + sizeof tbl, 0); ! 70: fread(seekpts, (sizeof seekpts[0]), 2, inf); ! 71: } while ((sflag && seekpts[1] - seekpts[0] > SLEN) ! 72: || (lflag && seekpts[1] - seekpts[0] < SLEN)); ! 73: fseek(inf, seekpts[0], 0); ! 74: while (c = getc(inf)) { ! 75: nchar++; ! 76: putchar(c); ! 77: } ! 78: fflush(stdout); ! 79: if (wflag) ! 80: sleep(max((int) nchar/CPERS, MINW)); ! 81: } ! 82: /* ! 83: * This routine evaluates the arguments on the command line ! 84: */ ! 85: getargs(ac, av) ! 86: int ac; ! 87: reg char *av[]; { ! 88: ! 89: reg short bad = 0; ! 90: reg int i, j; ! 91: ! 92: for (i = 1; i < ac; i++) { ! 93: if (av[i][0] != '-') ! 94: strcpy(fortfile, av[i]); ! 95: else ! 96: switch (av[i][1]) { ! 97: case '\0': /* give usage */ ! 98: for (j = 0; j < sizeof usage / sizeof (char *); j++) ! 99: puts(usage[j]); ! 100: exit(0); ! 101: case 'w': /* give time to read */ ! 102: wflag++; ! 103: break; ! 104: case 's': /* short ones only */ ! 105: sflag++; ! 106: break; ! 107: case 'l': /* long ones only */ ! 108: lflag++; ! 109: break; ! 110: case 'o': /* offensive ones only */ ! 111: oflag++; ! 112: break; ! 113: case 'a': /* any fortune */ ! 114: aflag++; ! 115: break; ! 116: default: ! 117: printf("unknown flag: '%c'\n", av[1][1]); ! 118: bad++; ! 119: break; ! 120: } ! 121: } ! 122: if (bad) { ! 123: printf("use \"%s -\" to get usage\n", av[0]); ! 124: exit(-1); ! 125: } ! 126: } ! 127: ! 128: max(i, j) ! 129: reg int i, j; { ! 130: ! 131: return (i >= j ? i : j); ! 132: } ! 133: ! 134: # ifndef vax ! 135: # define MAXRAND 32767L ! 136: ! 137: roll(ndie, nsides) ! 138: int ndie, nsides; { ! 139: ! 140: reg long tot; ! 141: reg unsigned n, r; ! 142: ! 143: tot = 0; ! 144: n = ndie; ! 145: while (n--) ! 146: tot += rand(); ! 147: return (int) ((tot * (long) nsides) / ((long) MAXRAND + 1)) + ndie; ! 148: } ! 149: ! 150: # else ! 151: ! 152: roll(ndie, nsides) ! 153: reg int ndie, nsides; { ! 154: ! 155: reg int tot, r; ! 156: reg double num_sides; ! 157: ! 158: num_sides = nsides; ! 159: tot = 0; ! 160: while (ndie--) ! 161: tot += rand() * (num_sides / 017777777777) + 1; ! 162: return tot; ! 163: } ! 164: # endif ! 165: ! 166:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.