Category : C Source Code
Archive   : CSRC1.ZIP
Filename : COOKIE.C

 
Output of file : COOKIE.C contained in archive : CSRC1.ZIP
/* C O O K I E
*
* Print a random cookie.
*
*/

/*)BUILD
*/

#ifdef DOCUMENTATION

title cookie Print a Random Message
index Print a Random Message

synopsis

cookie [options]

description

Cookie prints a fortune cookie. The options are:
.lm +8
.s.i- 8;-N Output N cookies.
.s.i- 8;N Output the Nth cookie.
.s.i- 8;-a Output all cookies in entry order.
cookie -a -a appends %% to each cookie (so that the
output file may be fed back to coobld).
.s.i -8;-f file Read cookies from this file. (Ignore
search list.)
.s.i- 8;-h Eliminate Heinlien and Lazarus Long cookies
.s.i- 8;-v Video mode -- Format for a VT52 or VT100
(VT100 assumed).
.s.i- 8;-vt52 Explicitly format for a VT52 or VT100 in VT52 mode
.s.i- 8;-vt100 Explicitly format for a VT100 in ANSI mode
.s.i- 8;-c Continuous -- give lots of random cookies
.s.i- 8;-s N Continuous with specified sleep interval. This may
also be specified "-sN". If no number is given, "-s 60" will be
assumed.
.s.i- 8;/HEINLIEN=NO##Same as -h, but for VMS systems
.s.lm -8
To enable elimination of cookies by Robert A. Heinlien and his alter
ego Lazarus Long, define "NOHEINLIEN". If eliminated, a suitable
anticookie will be presented.
.s
Cookie uses the following search list to locate the cookie file:
.s.nf
[]cookie.fil
sys_cookie:cookie.fil
public:cookie.fil
pub:cookie.fil
sys$public:cookie.fil
games:cookie.fil
sys$games:cookie.fil
_dbb1:[game]cookie.fil
.s.f

author

Martin Minow

bugs

#endif

#define NOHEINLIEN 1

#include
#define EOS 0
#define TRUE 1
#define FALSE 0
#ifdef rsx
#define R_MODE "run"
#else
#ifdef rt11
#define R_MODE "rn"
#else
#define R_MODE "r"
#endif
#endif
int $$narg = 1; /* No argv> prompt */

extern int $$rsts;

extern long rand();
extern long seed;
extern long time();

#define EOS 0

int doall = 0;
int video = 0;
int isvt52 = 0;
int notLong = 0; /* nor Heinlien */
int continuous = 0;
int long_sleep = 0;
int cur_line = 0;
int linecount = 0;
char *old_buff = NULL;
char sc_buff[121];
char temp_text[81];

FILE *cookfd = NULL;
char *cookfile[] = { /* Cookie search list */
"cookie.fil", /* Current directory first */
"sys_cookie:cookie.fil", /* Default cookie directory */
"public:cookie.fil", /* Various */
"pub:cookie.fil", /* public */
"sys$public:cookie.fil", /* directories */
"games:cookie.fil", /* Some */
"game:cookie.fil", /* games */
"sys$games:cookie.fil", /* directories */
"_dbb1:[game]cookie.fil", /* PHENIX games directory */
NULL,
};

struct header {
long ncookie; /* Number of cookies */
int nindex; /* Dimension of index[] */
int subindex; /* Number of subindex entries */
int sindex; /* Sizeof index for alloc */
char date[28]; /* Date cookie file built */
} header;

#define NCOOKIES (header.ncookie)
#define TEXTSIZE 2048
#define INDEXMAX (TEXTSIZE / sizeof (long))

union {
char text[TEXTSIZE]; /* Cookies stored here */
long index[INDEXMAX]; /* Cookie sub index entries */
} t;

/*
* If only one cookie is needed, topindex[] can be overlayed over t.index[]
*/

long topindex[INDEXMAX]; /* Top index entries */

main(argc, argv)
int argc;
char *argv[];
{
register int howmany; /* How many to do */
register char *ap;
register int outtime;
long which;
long atol();

which = 0;
while (argc > 1) {
ap = argv[1];
if (isdigit(*ap) || (*ap == '-' && isdigit(ap[1])))
which = atol(ap);
else if (*ap != '-') {
#ifdef NOHEINLIEN
if (streq(ap, "/HEINLIEN=NO")
|| streq(ap, "/heinlien=no"))
notLong++;
else
#endif
fprintf(stderr, "?Unknown command \"%s\"\n", ap);
}
else for (ap++; *ap; ap++) {
switch (tolower(*ap)) {
case 'a':
doall++;
break;

case 'c':
continuous++;
break;

case 'f':
if ((cookfd = fopen(argv[2], R_MODE)) == NULL) {
perror(argv[2]);
exit(IO_ERROR);
}
argv++;
argc--;
goto next_arg;

#ifdef NOHEINLIEN
case 'h':
notLong++; /* No (Lazarus) Longs */
break;
#endif
case 's': /* Long sleep */
continuous++;
if (isdigit(ap[1])) {
long_sleep = atoi(&ap[1]);
}
else if (isdigit(argv[2][0])) {
long_sleep = atoi(argv[2]);
argv++; /* Skip next argument */
argc--; /* too. */
}
else {
long_sleep = 60;
break;
}
goto next_arg;

case 'v':
video = 1;
if (tolower(ap[1]) == 't') {
video = atoi(&ap[2]);
if (video == 52)
isvt52 = 1;
else if (video == 100)
isvt52 = 0;
else
fprintf(stderr, "?Unknown video \"%s\"\n", ap);
while (*ap)
ap++;
}
break;

default:
fprintf(stderr, "?Unknown option '%c'\n", *ap);
}
}
next_arg:
argc--;
argv++;
}
init(); /* Setup random number */
setup_cookie();
if (video)
erpage(1, 1);
if (doall) {
for (which = 1; which <= NCOOKIES; which++) {
docookie(which);
}
}
if (continuous)
which = -1;
if (which > 0) {
if (which > NCOOKIES) {
sprintf(t.text, "Misfortune: there are only %ld cookies.\n",
NCOOKIES);
output(which, t.text);
}
else
docookie(which);
}
else {
if ((howmany = -which) == 0)
howmany = 1;
while (howmany-- > 0) {
which = irand((int) NCOOKIES);
docookie(which + 1);
if (continuous)
howmany = 1;
if (howmany > 0) {
sleep((long_sleep > 0)
? long_sleep : (linecount + 1) * 2);
}
}
}
}

int
irand(max)
int max;
/*
* Rand mod max
*/
{
long temp;

temp = rand();
temp = temp ^ (temp >> 16);
temp &= 32767;
temp *= max;
return ((int) (temp / 32768L));
}

init()
/*
* Initialize random number generator
*/
{
union {
long lvec; /* For time of day */
int ivec[2];
} tbuf;
register int i;
register int j;

time(&tbuf.lvec); /* Setup random number */
seed = tbuf.lvec;
j = rand(0);
i = rand(0);
i = i ^ (~tbuf.ivec[0] ^ tbuf.ivec[1]);
/* random number */
i = (j ^ i) & 15; /* generator */
do { /* call rand() 1 .. 16 */
rand(); /* times. */
} while (i-- > 0);
}

setup_cookie()
/*
* Initialize cookie file, finding it in the search list
*/
{
register char **namep;
register int temp;

if (cookfd == NULL) {
for (namep = cookfile; *namep != NULL; namep++) {
if ((cookfd = fopen(*namep, R_MODE)) != NULL)
break;
}
if (cookfd == NULL)
error("Can't open cookie file\n");
}
#ifdef rsx
if ((temp = fget(&header, sizeof header, cookfd)) != sizeof header)
rerror(sizeof header, temp, "Reading header file");
if ((temp = fget(&topindex, header.sindex, cookfd)) != header.sindex)
rerror(header.sindex, temp, "Reading top-level index");
#else
if ((temp = fread(&header, sizeof header, 1, cookfd)) != 1)
rerror(sizeof header, temp, "Reading header file");
if ((temp = fread(&topindex, header.sindex, 1, cookfd)) != 1)
rerror(header.sindex, temp, "Reading top-level index");
#endif
}

rerror(expected, got, why)
int expected; /* Bytes in item */
int got; /* Unexpectedly isn't == 1 */
char *why;
/*
* Fatal read error
*/
{
perror(why);
#ifdef rsx
fprintf(stderr, "expected %d bytes, read %d bytes\n",
expected, got);
#else
fprintf(stderr, "expected 1 item of %d bytes, read %d items\n",
expected, got);
#endif
/* error("Can't continue");
*/
}

docookie(which)
long which;
/*
* Read and output the Nth cookie. Note: 1-origin addressing
*/
{
long index;
long temp;
register int bytect;
register int i;
register char *tp;

which--;
temp = header.nindex;
temp = which / temp;
i = temp;
if (i >= header.subindex)
error("Bug: Gone too far, index = %d, max = %d\n",
i, header.subindex);
index = topindex[i];
if (fseek(cookfd, index, 0) != 0)
error("Can't seek to top_index at %ld, error = %06o\n",
index, $$ferr);
$$ferr = 0;
#ifdef rsx
if ((bytect = fget(&t.index, header.sindex, cookfd)) != header.sindex) {
#else
if ((bytect = fread(&t.index, header.sindex, 1, cookfd)) != 1) {
#endif
fprintf(stderr, "seek to sub-index %d, %ld. %06o %06o\n",
i, index, index);
rerror(header.sindex, bytect, "Can't read sub_index");
}
temp = header.nindex;
temp = which % temp;
i = temp;
index = t.index[i];
if (fseek(cookfd, index, 0) != 0) {
fprintf(stderr, "?Can't seek to cookie at %ld, code = %06o: ",
index, $$ferr);
perror("minor index seek");
error("?Requesting cookie %ld, max = %ld\n",
which, header.ncookie);
return;
}
tp = &t.text[0];
#ifdef rsx
while (fget(tp, (sizeof t.text) - (tp - t.text), cookfd) > 0
#else
while (fgets(tp, (sizeof t.text) - (tp - t.text), cookfd) != NULL
#endif
&& !feof(cookfd)
&& tp[0] != '%'
&& tp[1] != '%') {
tp += strlen(tp);
}
*tp = EOS; /* Remove trailing %% */
if (feof(cookfd)) {
rerror(tp - t.text, tp - t.text, "Can't read cookie");
}
if (notLong && isLong(t.text))
antiheinlien(which + 1);
else
output(which + 1, &t.text);
}

static char *anti1[] = {
"A Heinlien Cookie you do distain,\n\
I'll say no more to soothe your brain.",
"I'd rather drink a gallon of overage Rhine wine,\n\
Than read a quote by Robert A. Heinlien.",
"I'd rather bite boils from an elephant's behind,\n\
Than read more quotes by Robert A. Heinlien.",
"*I'd rather a tax audit found me wrong,",
"*I'd rather be dribbled by old King Kong,",
"*I'd rather find paraquat in my bong,",
"*I'd rather Chuck Barris used me as the gong,",
"*I'd rather do updates to Atari Pong,",
"*I'd rather write a \"User's Guide to Pong\",",
};

static char *anti2[] = {
"Than read another quote by Lazarus Long.",
"Than have to read more of Lazarus Long.",
"Than be forced to consider more Lazarus Long.",
};

isLong(text)
register char *text;
/*
* Return TRUE if the text contains "Heinlien" or "Lazarus Long"
*/
{
register char c;

while ((c = *text++) != EOS) {
switch (c) {

case 'H':
if (streq(text, "einlien"))
return (TRUE);
break;

case 'L':
if (streq(text, "azarus Long"))
return (TRUE);
break;
}
}
return (FALSE);
}

static char antibuffer[257];

antiheinlien(which)
long which;
/*
* Output a non-Heinlien cookie
*/
{
register char *tp;


tp = anti1[(rand() & 32767) % (sizeof anti1) / (sizeof (char *))];
if (*tp == '*') {
strcpy(antibuffer, tp + 1);
*tp++ = '\n';
strcat(tp,
anti2[(rand() & 32767) % (sizeof anti2) / (sizeof (char *))]);
}
else {
strcpy(antibuffer, tp);
}
output(which, antibuffer);
}

output(which, out_text)
long which;
char *out_text;
/*
* Output one cookie
*/
{
register char *tp;

startoutput(which);
printf("%s%s\n", out_text, (doall > 1) ? "%%" : "");
linecount = 1;
tp = out_text;
if ((tp = strchr(tp, '\n')) != NULL) {
linecount++;
tp++;
}
endoutput();
}

startout(which)
long which;
/*
* Initialize output
*/
{

register char *timebuf;
int tvec[2];

if (video) {
sprintf(temp_text, "%ld", which);
time(&tvec);
timebuf = ctime(&tvec);
erpage(1, 1);
if (isvt52) {
/*
* VT52
*/
vtout(1, 27, timebuf);
vtout(3, 36, temp_text);
}
else {
/*
* VT100
*/
if ($$rsts) {
vtout(1, 8, "\233#3"); /* Double high */
vtout(0, 0, timebuf); /* Top half */
vtout(2, 8, "\233#4"); /* Double high */
vtout(0, 0, timebuf); /* Bottom half */
vtout(3, 18, "\233#6"); /* Double wide */
vtout(0, 0, temp_text);
}
else {
vtout(1, 8, "\033#3"); /* Double high */
vtout(0, 0, timebuf); /* Top half */
vtout(2, 8, "\033#4"); /* Double high */
vtout(0, 0, timebuf); /* Bottom half */
vtout(3, 18, "\033#6"); /* Double wide */
vtout(0, 0, temp_text);
}
}
vtout(5, 1, "");
}
}

endoutput()

/*
* Clear the rest of the screen
*/
{
if (video) {
erpage(0, 0);
fflush(stdout);
}
}

vtcurse(row, col)
int row, col;
{
if (row == 0)
return;
if (isvt52) {
printf(($$rsts) ? "\233Y%c%c" : "\033Y%c%c",
row + 040, col + 040);
}
else {
printf(($$rsts) ? "\233[%d;%dH" : "\033[%d;%dH",
row, col);
}
}

erpage(row, col)
int row, col;
{
vtcurse(row, col);
if (isvt52)
fputs(($$rsts) ? "\233J" : "\033J", stdout);
else
fputs(($$rsts) ? "\233[J" : "\033[J", stdout);
}

erline(row, col)
int row, col;
{
vtcurse(row, col);
if (isvt52)
fputs(($$rsts) ? "\233K" : "\033K", stdout);
else
fputs(($$rsts) ? "\233[K" : "\033[K", stdout);
}

vtout(row, col, text)
int row, col;
char *text;
{
vtcurse(row, col);
fputs(text, stdout);
}



  3 Responses to “Category : C Source Code
Archive   : CSRC1.ZIP
Filename : COOKIE.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/