🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: net.sources.games
Article #47

Fortune(6) program.

#47
From: Curt J. Sampson his home compute...
Date: Mon, 25 Feb 1985 02:53
522 lines
15083 bytes
This is a version of fortune that I wrote.  It allows multiple line fortunes,
and uses an indexed fortune file to speed it up.  To install it, simply su
root (or games, if you use a seperate id) and type `make install'.  I have
included a few fortunes, but you will probably want to add more yourself.
If you are using a C compiler with fewer than 12 character identifiers, you
will have to change the names of a few of the variables.  Otherwise it
should run anywhere.  I have tested it on a VAX-11/780 running 4.2 BSD and
an Altos 586 running XENIX.

Send any bug reports, etc. to me.
=====================================================================
	Curt Sampson		ihnp4!alberta!jeff
---------------------------------------------------------------------

-------------------------- TEAR HERE ----------------------------
# This is a shell archive.  Remove anything before this line, then
# unpack it by saving it in a file and typing "sh file".  (Files
# unpacked will be owned by you and have default permissions.)
#
# This archive contains:
# Makefile READ_ME fortune.6 fortune.c fortune.h fortunes makefortunes.6 makefortunes.c

echo x - Makefile
cat > "Makefile" << '//E*O*F Makefile//'
#
# Makefile for `fortune'
#
# by Curt Sampson
# v1.0  1 Feb. 1985
#

DEST=/usr/games
LIB=/usr/games/lib
MAN=/usr/man/man6
FORTUNES=${LIB}/fortunes.dat

all: fortune makefortunes

fortune: fortune.h fortune.o
	cc fortune.o -o fortune -DFORTUNEFILE=${FORTUNES}

makefortunes: fortune.h makefortunes.o
	cc makefortunes.o -o makefortunes

install: all
	mv fortune ${DEST}
	mv makefortunes ${LIB}
	mv fortune.6 ${MAN}
	${LIB}/makefortunes ${FORTUNES} fortunes

clean:
	-rm *.o
//E*O*F Makefile//

echo x - READ_ME
cat > "READ_ME" << '//E*O*F READ_ME//'
This is a version of the UNIX(tm) `fortune' program.  It dispenses small
snippets of wisdom every time it is called.  I have set it up so that it
uses and indexed file to speed things up and allow multi-line fortunes.
To set up an indexed file of fortunes, say `makefortune fortunes.dat fortunes'.
It will take the fortunes in `fortunes', index them, and put them in
`fortunes.dat'.  If you wish to use your own file in place of `fortunes',
simply type in the fortunes and seperate them with a line that has only a
period (`.') on it.  You may use blank lines, and the like, but do not use
the fortune seperation character (normally '\001' or Control-A).  Then just
install it and run.  You may use a private fortune file by giving fortune
the filename as an argument.  Send bugs, fixes, questions, etc. to the
address below.  That's about it.  Have fun!

					Curt J. Sampson
					ihnp4!alberta!jeff
//E*O*F READ_ME//

echo x - fortune.6
cat > "fortune.6" << '//E*O*F fortune.6//'
.TH FORTUNE 6 "1 February 1985"
.SH NAME
fortune \- print a random, hopefully interesting, adage
.SH SYNOPSIS
.B /usr/games/fortune
[ file ]
.SH DESCRIPTION
.I Fortune
with no arguments prints out a random adage.  The argument `file' uses
an alternate list of fortunes supplied by the user.
.SH FILES
/usr/games/lib/fortunes.dat	default fortunes file
.SH AUTHOR
Curt J. Sampson
.br
ihnp4!alberta!jeff
.SH SEE\ ALSO
makefortunes(6)
//E*O*F fortune.6//

echo x - fortune.c
cat > "fortune.c" << '//E*O*F fortune.c//'
/*
 * fortune.c
 *
 * by Curt Sampson
 * v0.1  1 Feb. 1984
 *
 * Usage:
 *	fortune [file]
 *
 * This will pick a random fortune out of a fortunes file or <file> if
 * specified and print it.  The fortunes file must be indexed by
 * `makefortunes'.
 *
 */

#include "fortune.h"

main(argc, argv)
int argc;
char *argv[];
{
	FILE	*fortunefile;		/* file of fortunes */
	int	fortune;		/* fortune selected */
	long	offset,			/* offset of fortune into file */
		numfortunes;		/* number of fortunes */
	char	c;			/* for the fortune itself */


	if ( argc > 2 )  {
		puts("Usage: fortune [ file ]");
		exit(1);
	}

	/* open file */
	if ( argc == 2 )  {	/* use argument as file */
		if ( (fortunefile = fopen(argv[1], "r")) == NULL )  {
			fprintf(stderr, "fortune: can't open %s\n", argv[1]);
			exit(1);
		}
	} else {		/* use default file */
		if ( (fortunefile = fopen(FORTUNEFILE, "r")) == NULL )  {
			fputs("fortune: can't open fortunes file", stderr);
			exit(1);
		}
	}

	/* find out how many fortunes there are */
	if ( fread(&numfortunes, sizeof(numfortunes), 1, fortunefile) == 0 )  {
		fputs("fortune: can't read fortunes", stderr);
		exit(1);
	}

	/* seed random number generator and get random fortune number */
	(void) srand((int) time());
	fortune = rand() % numfortunes;
	
	/* find offset into fortune file */
	if ( fseek(fortunefile, (long)(fortune * sizeof(offset)), 1) == -1 )  {
		fputs("fortune: offset seek failed", stderr);
		exit(1);
	}
	if ( fread(&offset, sizeof(offset), 1, fortunefile) == NULL )  {
		fputs("fortune: offset read failed", stderr);
		exit(1);
	}

	/* get to the end of the offset info */
	if ( fseek(fortunefile, (long)(((numfortunes - 1) - fortune)
	   * sizeof(offset)), 1) == -1 )  {
		fputs("fortune: offset reseek failed", stderr);
		exit(1);
	}

	/* find the fortune */
	if ( fseek(fortunefile, (long) offset, 1) == -1 )  {
		fputs("fortune: fortune seek failed", stderr);
		exit(1);
	}

	/* print the fortune */
	while ( (c = getc(fortunefile)) != ENDOFFORTUNE ) 
		putchar(c);
	
	(void) fclose(fortunefile);
	(void) exit(0);

}
//E*O*F fortune.c//

echo x - fortune.h
cat > "fortune.h" << '//E*O*F fortune.h//'
#include <stdio.h>

#ifndef TRUE
#define TRUE	1
#endif

#ifndef	FALSE
#define FALSE	0
#endif

#define ENDOFFORTUNE	'\001'
#define TXTENDOFFORTUNE	".\n"
#define LINELEN		1024

#ifndef FORTUNEFILE
#define FORTUNEFILE	"/usr/games/lib/fortunes.dat"
#endif
//E*O*F fortune.h//

echo x - fortunes
cat > "fortunes" << '//E*O*F fortunes//'
Q: What's the difference between a Mac and an Etch-a-Sketch?
A: You don't have to shake the Mac to clear the screen.
.
Reactor error - core dumped!
.
Help!  I'm trapped inside a DEC PDP-11!
.
!11-PDP CED a edisni deppart m`I  !pleH
.
This is a fill in the blank fortune: ________________________________________.
.
Don't burn your chickens before you cross the road.
.
If at first you don't succeed, redefine success.
.
Arithmetic is being able to count up to twenty without taking off your
shoes.
		-- Mickey Mouse
.
The human animal differs from the lesser primates in his passion for
lists of "Ten Best".
		-- H. Allen Smith
.
Parkinson's Fifth Law:
	If there is a way to delay in important decision, the good
	bureaucracy, public or private, will find it.
.
Two Observations on English Grammer:
	1) People tend to carelessly split infinitives.
	2) A preposition is a bad thing to end a sentence with.
.
Hofstadter's Law:
	It always takes longer than you expect, even if you take Hofstadter's
	Law into account.
.
Jones' First Law:
	Anyone who makes a significant contribution to any field of
	endeavor, and stays in that field long enough, becomes an
	obstruction to its progress -- in direct proportion to the
	importance of their original contribution.
.
If the odds are a million to one against something occurring, chances
are 50-50 it will.
.
If you think the pen is mightier than the sword, the next time someone pulls
out a sword I'd like to see you get up there with your Bic...
.
What this country needs is a good five-cent nickel.
.
What this country needs is a good five-cent anything!
.
"It looked like something resembling white marble, which was probably
 what is was: something resembling white marble."
				-- Douglas Adams,
				   "The Hitchhikers Guide to the Galaxy"
.
"Only great masters of style can succeed in being obtuse."
				-- Oscar Wilde
"Most UNIX programmers are great masters of style."
				-- Unnamed Usenetter
.
"Nothing lasts forever."
"Where do I find nothing?"
.
I'm sorry, but my kharma just ran over your dogma.
.
May you live in interesting times.
			-- Ancient Chinese Curse
.
We'll be recording at the Paradise Friday night.  Live, on the Death label.
.
This is fortune pledge week.  If you read this fortunes, why don't you mail
in a contribution to `fortune'.  Just to show you some of the really good
fortunes we have coming up...
.
ROMEO: Courage, man; the hurt cannot be much.
MERCUTIO: No, 'tis not so deep as a well, nor so wide as a church-
	door; but 'tis enough, 'twill serve.
.
Bus error -- please leave by the rear door.
.
//E*O*F fortunes//

echo x - makefortunes.6
cat > "makefortunes.6" << '//E*O*F makefortunes.6//'
.TH MAKEFORTUNES 6
.SH NAME
makefortunes \- create an indexed file for fortune(6)
.SH SYNOPSIS
.B /usr/games/lib/makefortunes
output input
.SH DESCRIPTION
.I makefortunes
creates an indexed file that can be used by fortune(6).
.I output
will be the indexed file.
.I input
should consist of fortunes seperated by lines with only a period ('.').
Special characters and blank lines may be used freely with the execption
of the end-of-fortune character, which is normally '\\001' or control-A.
.SH AUTHOR
Curt J. Sampson
.br
ihnp4!alberta!jeff
.SH SEE\ ALSO
fortune(6)
//E*O*F makefortunes.6//

echo x - makefortunes.c
cat > "makefortunes.c" << '//E*O*F makefortunes.c//'
/*
 *  makefortunes.c
 *
 *  by Curt Sampson
 *  v0.1  1 Feb. 1985
 *
 *  Usage:
 *	makefortunes <output> <fortunes>
 *
 *  This program will take the contents of the file <fortunes> and
 *  build a new file <output> that has an index and the fortunes in
 *  it so that a fast lookup can be made by `fortune'.  The <fortunes>
 *  file should have the individaul fortunes seperated by a line with
 *  only a period on it.
 *
 */

#include "fortune.h"

main(argc, argv)
int argc;
char *argv[];
{
	char	*mktemp();		/* declare library functions */

	char	inputfilname[25],	/* input and output file names */
		outputfilname[25],
		tmptxtfilname[25],	/* tempory files for fortunes */
		tmpindxfilname[25];	/* and index */
	FILE	*inputfil,		/* pointers to files for fread() */
		*outputfil,
		*tmptxt,
		*tmpindx;
	long	offset,			/* count of offset of fortunes */
		numfortunes;		/* number of fortunes */
	int	fortlen;		/* length of current fortune */


	if ( argc != 3 )  {
		fputs("Usage: makefortunes <output> <fortunes>\n", stderr);
		exit(1);
	}

	/* construct file names */

	(void) strcpy(outputfilname, argv[1]);
	(void) strcpy(inputfilname, argv[2]);

	(void) strcpy(tmptxtfilname, (void) mktemp("/tmp/forfXXXXXX"));
	(void) strcpy(tmpindxfilname, (void) mktemp("/tmp/foriXXXXXX"));

	/* open files needed */

	if ( (inputfil = fopen(inputfilname, "r")) == NULL )  {
		fprintf(stderr, "makefortunes: can't open %s\n", inputfilname);
		exit(1);
	}
	(void) unlink(tmptxtfilname);
	if ( (tmptxt = fopen(tmptxtfilname, "a")) == NULL )  {
		puts("makefortunes: can't create temporary text file", stderr);
		exit(1);
	}
	(void) unlink(tmpindxfilname);
	if ( (tmpindx = fopen(tmpindxfilname, "a")) == NULL )  {
		puts("makefortunes: can't create temporary index file", stderr);
		exit(1);
	}

	/* copy the fortunes and determine the offsets */

	offset = 0;
	numfortunes = 0;

	while ( (fortlen = getnextfortune(inputfil, tmptxt)) != 0 )  {
		/* write offset */
		fwrite(&offset, sizeof(offset), 1, tmpindx);
		offset += fortlen;
		++numfortunes;
	}

	/* close files and reopen for reading */

	if ( (fclose(inputfil)) == EOF )  {
		fprintf(stderr, "makefortunes: can't close %s\n", inputfilname);
		exit(1);
	}
	if ( (fclose(tmptxt)) == EOF )  {
		fputs("makefortunes: can't close temporary text file", stderr);
		exit(1);
	}
	if ( (fclose(tmpindx)) == EOF )  {
		fputs("makefortunes: can't close temporary index file", stderr);
		exit(1);
	}

	if ( (tmptxt = fopen(tmptxtfilname, "r")) == NULL )  {
		puts("makefortunes: can't open temporary text file", stderr);
		exit(1);
	}
	if ( (tmpindx = fopen(tmpindxfilname, "r")) == NULL )  {
		puts("makefortunes: can't open temporary index file", stderr);
		exit(1);
	}

	/* now write main fortunes file */

	(void) unlink(outputfilname);
	if ( (outputfil = fopen(outputfilname, "a")) == NULL )  {  /* create */
		fprintf(stderr, "makefortunes: can't create %s\n",
			outputfilname);
		exit(1);
	}

	if ( fwrite(&numfortunes, sizeof(numfortunes), 1, outputfil) == 0 )  {
		fputs("makefortunes: can't write number of fortunes", stderr);
		exit(1);
	}

	if ( (fclose(outputfil)) == EOF )  {
		fprintf(stderr, "makefortunes: can't close %s\n",outputfilname);
		exit(1);
	}

	if ( (append(outputfilname, tmpindxfilname)) == 1 )  {
		fprintf(stderr, "makefortunes: can't append temporary\
			index file to %s", outputfilname);
		exit(1);
	}

	if ( (append(outputfilname, tmptxtfilname)) == 1 )  {
		fprintf(stderr, "makefortunes: can't append temporary\
			text file to %s", outputfilname);
		exit(1);
	}

	/* all done! */
	exit(0);

}

/*
 * getnextfortune(infile, out)
 *
 * gets next fortune from <infile>, writes it to <outfile> with a ENDOFFORTUNE
 * after it, and returns the length of the fortune including the ENDOFFORTUNE.
 * It returns 0 if no more fortunes are left.
 * Fortune in <infile> has TXTENDOFFORTUNE on a line alone to signify its end.
 */

int getnextfortune(inputfile, outputfile)
FILE *inputfile,
     *outputfile;
{
	int	len,				/* length of fortune */
		done;
	char	inputline[LINELEN];		/* input line */

	len = 0;

	if ( (fgets(inputline, LINELEN, inputfile)) == NULL )
		return(0);

	done = FALSE;
	while ( ! done )  {
		if (strcmp(inputline, TXTENDOFFORTUNE) == 0)  {
			done = TRUE;
			continue;
		}
		len += strlen(inputline);
		fputs(inputline, outputfile);
		if ( (fgets(inputline, LINELEN, inputfile)) == NULL )  {
			done = TRUE;
			continue;
		}
	}
	putc(ENDOFFORTUNE, outputfile);
	len += 1;

	return(len);
}

/*
 * append(to, from)
 *
 * appends the file <from> to the file <to>
 * returns 0 if successful, 1 if an error occurs
 */

int append(toname, fromname)
char *toname,
     *fromname;
{
	char	cmd[128];	/* command to execute via system() */

	sprintf(cmd, "cat %s >>%s", fromname, toname);
	if ( (system(cmd)) == 127 )
		return(1);

	return(0);
}
//E*O*F makefortunes.c//

exit 0
Technical Details
Message-ID: <417@alberta.UUCP>
Path: arc1-ca.pugleaf.net!utzoo!watmath!clyde!cbosgd!ihnp4!alberta!jeff@alberta (Curt J. Sampson @ his home computer)

Show Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10.2 9/5/84; site alberta.UUCP
Path: arc1-ca.pugleaf.net!utzoo!watmath!clyde!cbosgd!ihnp4!alberta!jeff@alberta (Curt J. Sampson @ his home computer)
From: jeff@alberta (Curt J. Sampson @ his home computer)
Newsgroups: net.sources.games
Subject: Fortune(6) program.
Message-ID: <417@alberta.UUCP>
Date: Sun, 24-Feb-85 21:53:50 EST
Article-I.D.: alberta.417
Posted: Sun Feb 24 21:53:50 1985
Date-Received: Wed, 27-Feb-85 05:32:07 EST
Sender: jeff@alberta.UUCP
Reply-To: jeff@alberta
Distribution: net
Organization: his Personal Computer
Lines: 522