xref: /openbsd/games/fish/fish.c (revision 6fa5e1da)
1*6fa5e1daSmestre /*	$OpenBSD: fish.c,v 1.23 2016/03/07 12:07:56 mestre Exp $	*/
2df930be7Sderaadt /*	$NetBSD: fish.c,v 1.3 1995/03/23 08:28:18 cgd Exp $	*/
3df930be7Sderaadt 
4df930be7Sderaadt /*-
5df930be7Sderaadt  * Copyright (c) 1990, 1993
6df930be7Sderaadt  *	The Regents of the University of California.  All rights reserved.
7df930be7Sderaadt  *
8df930be7Sderaadt  * This code is derived from software contributed to Berkeley by
9df930be7Sderaadt  * Muffy Barkocy.
10df930be7Sderaadt  *
11df930be7Sderaadt  * Redistribution and use in source and binary forms, with or without
12df930be7Sderaadt  * modification, are permitted provided that the following conditions
13df930be7Sderaadt  * are met:
14df930be7Sderaadt  * 1. Redistributions of source code must retain the above copyright
15df930be7Sderaadt  *    notice, this list of conditions and the following disclaimer.
16df930be7Sderaadt  * 2. Redistributions in binary form must reproduce the above copyright
17df930be7Sderaadt  *    notice, this list of conditions and the following disclaimer in the
18df930be7Sderaadt  *    documentation and/or other materials provided with the distribution.
197a09557bSmillert  * 3. Neither the name of the University nor the names of its contributors
20df930be7Sderaadt  *    may be used to endorse or promote products derived from this software
21df930be7Sderaadt  *    without specific prior written permission.
22df930be7Sderaadt  *
23df930be7Sderaadt  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24df930be7Sderaadt  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25df930be7Sderaadt  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26df930be7Sderaadt  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27df930be7Sderaadt  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28df930be7Sderaadt  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29df930be7Sderaadt  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30df930be7Sderaadt  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31df930be7Sderaadt  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32df930be7Sderaadt  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33df930be7Sderaadt  * SUCH DAMAGE.
34df930be7Sderaadt  */
35df930be7Sderaadt 
3696b46b10Spjanzen #include <sys/wait.h>
379ea8ec70Smestre 
3896b46b10Spjanzen #include <err.h>
39df930be7Sderaadt #include <fcntl.h>
4096b46b10Spjanzen #include <paths.h>
41df930be7Sderaadt #include <stdio.h>
42df930be7Sderaadt #include <stdlib.h>
43df930be7Sderaadt #include <string.h>
44bdf3894fSmestre #include <unistd.h>
459ea8ec70Smestre 
46df930be7Sderaadt #include "pathnames.h"
47df930be7Sderaadt 
48df930be7Sderaadt #define	RANKS		13
49df930be7Sderaadt #define	HANDSIZE	7
50df930be7Sderaadt #define	CARDS		4
51c61e1f0cSpjanzen #define	TOTCARDS	RANKS * CARDS
52df930be7Sderaadt 
53df930be7Sderaadt #define	USER		1
54df930be7Sderaadt #define	COMPUTER	0
55df930be7Sderaadt #define	OTHER(a)	(1 - (a))
56df930be7Sderaadt 
577faebae9Spjanzen const char *const cards[] = {
58df930be7Sderaadt 	"A", "2", "3", "4", "5", "6", "7",
59df930be7Sderaadt 	"8", "9", "10", "J", "Q", "K", NULL,
60df930be7Sderaadt };
61df930be7Sderaadt #define	PRC(card)	(void)printf(" %s", cards[card])
62df930be7Sderaadt 
63df930be7Sderaadt int promode;
64c61e1f0cSpjanzen int curcard;
65c61e1f0cSpjanzen int asked[RANKS], comphand[RANKS], deck[TOTCARDS];
66df930be7Sderaadt int userasked[RANKS], userhand[RANKS];
67df930be7Sderaadt 
68c72b5b24Smillert void	chkwinner(int, const int *);
69c72b5b24Smillert int	compmove(void);
70c72b5b24Smillert int	countbooks(const int *);
71c72b5b24Smillert int	countcards(const int *);
72c72b5b24Smillert int	drawcard(int, int *);
73c72b5b24Smillert int	getans(const char *);
74c72b5b24Smillert int	gofish(int, int, int *);
75c72b5b24Smillert void	goodmove(int, int, int *, int *);
76c72b5b24Smillert void	init(void);
77c72b5b24Smillert void	instructions(void);
78c72b5b24Smillert int	nrandom(int);
79c72b5b24Smillert void	printhand(const int *);
80c72b5b24Smillert void	printplayer(int);
81c72b5b24Smillert int	promove(void);
82f0628b46Smestre __dead void	usage(void);
83c72b5b24Smillert int	usermove(void);
84995ddd3bSpjanzen 
85995ddd3bSpjanzen int
main(int argc,char * argv[])863eb8c9edSjsg main(int argc, char *argv[])
87df930be7Sderaadt {
88df930be7Sderaadt 	int ch, move;
89df930be7Sderaadt 
9095ae2554Stb 	if (pledge("stdio rpath proc exec", NULL) == -1)
9195ae2554Stb 		err(1, "pledge");
9295ae2554Stb 
93995ddd3bSpjanzen 	while ((ch = getopt(argc, argv, "ph")) != -1)
94df930be7Sderaadt 		switch(ch) {
95df930be7Sderaadt 		case 'p':
96df930be7Sderaadt 			promode = 1;
97df930be7Sderaadt 			break;
98995ddd3bSpjanzen 		case 'h':
99df930be7Sderaadt 		default:
1007faebae9Spjanzen 			usage();
101df930be7Sderaadt 		}
102df930be7Sderaadt 
103df930be7Sderaadt 	instructions();
10495ae2554Stb 
10595ae2554Stb 	if (pledge("stdio", NULL) == -1)
10695ae2554Stb 		err(1, "pledge");
10795ae2554Stb 
108df930be7Sderaadt 	init();
109df930be7Sderaadt 
110df930be7Sderaadt 	if (nrandom(2) == 1) {
111df930be7Sderaadt 		printplayer(COMPUTER);
112df930be7Sderaadt 		(void)printf("get to start.\n");
113df930be7Sderaadt 		goto istart;
114df930be7Sderaadt 	}
115df930be7Sderaadt 	printplayer(USER);
116df930be7Sderaadt 	(void)printf("get to start.\n");
117df930be7Sderaadt 
118df930be7Sderaadt 	for (;;) {
119df930be7Sderaadt 		move = usermove();
120df930be7Sderaadt 		if (!comphand[move]) {
121df930be7Sderaadt 			if (gofish(move, USER, userhand))
122df930be7Sderaadt 				continue;
123df930be7Sderaadt 		} else {
124df930be7Sderaadt 			goodmove(USER, move, userhand, comphand);
125df930be7Sderaadt 			continue;
126df930be7Sderaadt 		}
127df930be7Sderaadt 
128df930be7Sderaadt istart:		for (;;) {
129df930be7Sderaadt 			move = compmove();
130df930be7Sderaadt 			if (!userhand[move]) {
131df930be7Sderaadt 				if (!gofish(move, COMPUTER, comphand))
132df930be7Sderaadt 					break;
133df930be7Sderaadt 			} else
134df930be7Sderaadt 				goodmove(COMPUTER, move, comphand, userhand);
135df930be7Sderaadt 		}
136df930be7Sderaadt 	}
137df930be7Sderaadt }
138df930be7Sderaadt 
139995ddd3bSpjanzen int
usermove(void)1403eb8c9edSjsg usermove(void)
141df930be7Sderaadt {
1427faebae9Spjanzen 	int n;
1437faebae9Spjanzen 	const char *const *p;
144df930be7Sderaadt 	char buf[256];
145df930be7Sderaadt 
146df930be7Sderaadt 	(void)printf("\nYour hand is:");
147df930be7Sderaadt 	printhand(userhand);
148df930be7Sderaadt 
149df930be7Sderaadt 	for (;;) {
150df930be7Sderaadt 		(void)printf("You ask me for: ");
151df930be7Sderaadt 		(void)fflush(stdout);
15213fb7f4aSpjanzen 		if (fgets(buf, sizeof(buf), stdin) == NULL)
153df930be7Sderaadt 			exit(0);
154df930be7Sderaadt 		if (buf[0] == '\0')
155df930be7Sderaadt 			continue;
156df930be7Sderaadt 		if (buf[0] == '\n') {
157df930be7Sderaadt 			(void)printf("%d cards in my hand, %d in the pool.\n",
158c61e1f0cSpjanzen 			    countcards(comphand), curcard);
159df930be7Sderaadt 			(void)printf("My books:");
160df930be7Sderaadt 			(void)countbooks(comphand);
161df930be7Sderaadt 			continue;
162df930be7Sderaadt 		}
163df930be7Sderaadt 		buf[strlen(buf) - 1] = '\0';
164df930be7Sderaadt 		if (!strcasecmp(buf, "p") && !promode) {
165df930be7Sderaadt 			promode = 1;
166df930be7Sderaadt 			(void)printf("Entering pro mode.\n");
167df930be7Sderaadt 			continue;
168df930be7Sderaadt 		}
169df930be7Sderaadt 		if (!strcasecmp(buf, "quit"))
170df930be7Sderaadt 			exit(0);
171df930be7Sderaadt 		for (p = cards; *p; ++p)
172df930be7Sderaadt 			if (!strcasecmp(*p, buf))
173df930be7Sderaadt 				break;
174df930be7Sderaadt 		if (!*p) {
175df930be7Sderaadt 			(void)printf("I don't understand!\n");
176df930be7Sderaadt 			continue;
177df930be7Sderaadt 		}
178df930be7Sderaadt 		n = p - cards;
179df930be7Sderaadt 		if (userhand[n]) {
180df930be7Sderaadt 			userasked[n] = 1;
181df930be7Sderaadt 			return(n);
182df930be7Sderaadt 		}
183df930be7Sderaadt 		if (nrandom(3) == 1)
184df930be7Sderaadt 			(void)printf("You don't have any of those!\n");
185df930be7Sderaadt 		else
186df930be7Sderaadt 			(void)printf("You don't have any %s's!\n", cards[n]);
187df930be7Sderaadt 		if (nrandom(4) == 1)
188df930be7Sderaadt 			(void)printf("No cheating!\n");
189df930be7Sderaadt 		(void)printf("Guess again.\n");
190df930be7Sderaadt 	}
191df930be7Sderaadt }
192df930be7Sderaadt 
193995ddd3bSpjanzen int
compmove(void)1943eb8c9edSjsg compmove(void)
195df930be7Sderaadt {
196df930be7Sderaadt 	static int lmove;
197df930be7Sderaadt 
198df930be7Sderaadt 	if (promode)
199df930be7Sderaadt 		lmove = promove();
200df930be7Sderaadt 	else {
201df930be7Sderaadt 		do {
202df930be7Sderaadt 			lmove = (lmove + 1) % RANKS;
203df930be7Sderaadt 		} while (!comphand[lmove] || comphand[lmove] == CARDS);
204df930be7Sderaadt 	}
205df930be7Sderaadt 	asked[lmove] = 1;
206df930be7Sderaadt 
207df930be7Sderaadt 	(void)printf("I ask you for: %s.\n", cards[lmove]);
208df930be7Sderaadt 	return(lmove);
209df930be7Sderaadt }
210df930be7Sderaadt 
211995ddd3bSpjanzen int
promove(void)2123eb8c9edSjsg promove(void)
213df930be7Sderaadt {
2147faebae9Spjanzen 	int i, max;
215df930be7Sderaadt 
216df930be7Sderaadt 	for (i = 0; i < RANKS; ++i)
217df930be7Sderaadt 		if (userasked[i] &&
218df930be7Sderaadt 		    comphand[i] > 0 && comphand[i] < CARDS) {
219df930be7Sderaadt 			userasked[i] = 0;
220df930be7Sderaadt 			return(i);
221df930be7Sderaadt 		}
222df930be7Sderaadt 	if (nrandom(3) == 1) {
223df930be7Sderaadt 		for (i = 0;; ++i)
224df930be7Sderaadt 			if (comphand[i] && comphand[i] != CARDS) {
225df930be7Sderaadt 				max = i;
226df930be7Sderaadt 				break;
227df930be7Sderaadt 			}
228df930be7Sderaadt 		while (++i < RANKS)
229df930be7Sderaadt 			if (comphand[i] != CARDS &&
230df930be7Sderaadt 			    comphand[i] > comphand[max])
231df930be7Sderaadt 				max = i;
232df930be7Sderaadt 		return(max);
233df930be7Sderaadt 	}
234eb8dbf3eStedu 	if (nrandom(1024) == 723) {
235df930be7Sderaadt 		for (i = 0; i < RANKS; ++i)
236df930be7Sderaadt 			if (userhand[i] && comphand[i])
237df930be7Sderaadt 				return(i);
238df930be7Sderaadt 	}
239df930be7Sderaadt 	for (;;) {
240df930be7Sderaadt 		for (i = 0; i < RANKS; ++i)
241df930be7Sderaadt 			if (comphand[i] && comphand[i] != CARDS &&
242df930be7Sderaadt 			    !asked[i])
243df930be7Sderaadt 				return(i);
244df930be7Sderaadt 		for (i = 0; i < RANKS; ++i)
245df930be7Sderaadt 			asked[i] = 0;
246df930be7Sderaadt 	}
247df930be7Sderaadt }
248df930be7Sderaadt 
249995ddd3bSpjanzen int
drawcard(int player,int * hand)2503eb8c9edSjsg drawcard(int player, int *hand)
251df930be7Sderaadt {
252df930be7Sderaadt 	int card;
253df930be7Sderaadt 
254c61e1f0cSpjanzen 	++hand[card = deck[--curcard]];
255df930be7Sderaadt 	if (player == USER || hand[card] == CARDS) {
256df930be7Sderaadt 		printplayer(player);
257df930be7Sderaadt 		(void)printf("drew %s", cards[card]);
258df930be7Sderaadt 		if (hand[card] == CARDS) {
259df930be7Sderaadt 			(void)printf(" and made a book of %s's!\n",
260df930be7Sderaadt 			     cards[card]);
261df930be7Sderaadt 			chkwinner(player, hand);
262df930be7Sderaadt 		} else
263df930be7Sderaadt 			(void)printf(".\n");
264df930be7Sderaadt 	}
265df930be7Sderaadt 	return(card);
266df930be7Sderaadt }
267df930be7Sderaadt 
268995ddd3bSpjanzen int
gofish(int askedfor,int player,int * hand)2693eb8c9edSjsg gofish(int askedfor, int player, int *hand)
270df930be7Sderaadt {
271df930be7Sderaadt 	printplayer(OTHER(player));
272df930be7Sderaadt 	(void)printf("say \"GO FISH!\"\n");
273df930be7Sderaadt 	if (askedfor == drawcard(player, hand)) {
274df930be7Sderaadt 		printplayer(player);
275df930be7Sderaadt 		(void)printf("drew the guess!\n");
276df930be7Sderaadt 		printplayer(player);
277df930be7Sderaadt 		(void)printf("get to ask again!\n");
278df930be7Sderaadt 		return(1);
279df930be7Sderaadt 	}
280df930be7Sderaadt 	return(0);
281df930be7Sderaadt }
282df930be7Sderaadt 
283995ddd3bSpjanzen void
goodmove(int player,int move,int * hand,int * opphand)2843eb8c9edSjsg goodmove(int player, int move, int *hand, int *opphand)
285df930be7Sderaadt {
286df930be7Sderaadt 	printplayer(OTHER(player));
287df930be7Sderaadt 	(void)printf("have %d %s%s.\n",
288df930be7Sderaadt 	    opphand[move], cards[move], opphand[move] == 1 ? "": "'s");
289df930be7Sderaadt 
290df930be7Sderaadt 	hand[move] += opphand[move];
291df930be7Sderaadt 	opphand[move] = 0;
292df930be7Sderaadt 
293df930be7Sderaadt 	if (hand[move] == CARDS) {
294df930be7Sderaadt 		printplayer(player);
295df930be7Sderaadt 		(void)printf("made a book of %s's!\n", cards[move]);
296df930be7Sderaadt 		chkwinner(player, hand);
297df930be7Sderaadt 	}
298df930be7Sderaadt 
299df930be7Sderaadt 	chkwinner(OTHER(player), opphand);
300df930be7Sderaadt 
301df930be7Sderaadt 	printplayer(player);
302df930be7Sderaadt 	(void)printf("get another guess!\n");
303df930be7Sderaadt }
304df930be7Sderaadt 
305995ddd3bSpjanzen void
chkwinner(int player,const int * hand)3063eb8c9edSjsg chkwinner(int player, const int *hand)
307df930be7Sderaadt {
3087faebae9Spjanzen 	int cb, i, ub;
309df930be7Sderaadt 
310df930be7Sderaadt 	for (i = 0; i < RANKS; ++i)
311df930be7Sderaadt 		if (hand[i] > 0 && hand[i] < CARDS)
312df930be7Sderaadt 			return;
313df930be7Sderaadt 	printplayer(player);
314df930be7Sderaadt 	(void)printf("don't have any more cards!\n");
315df930be7Sderaadt 	(void)printf("My books:");
316df930be7Sderaadt 	cb = countbooks(comphand);
317df930be7Sderaadt 	(void)printf("Your books:");
318df930be7Sderaadt 	ub = countbooks(userhand);
319df930be7Sderaadt 	(void)printf("\nI have %d, you have %d.\n", cb, ub);
320df930be7Sderaadt 	if (ub > cb) {
321df930be7Sderaadt 		(void)printf("\nYou win!!!\n");
322eb8dbf3eStedu 		if (nrandom(1024) == 723)
323df930be7Sderaadt 			(void)printf("Cheater, cheater, pumpkin eater!\n");
324df930be7Sderaadt 	} else if (cb > ub) {
325df930be7Sderaadt 		(void)printf("\nI win!!!\n");
326eb8dbf3eStedu 		if (nrandom(1024) == 723)
327df930be7Sderaadt 			(void)printf("Hah!  Stupid peasant!\n");
328df930be7Sderaadt 	} else
329df930be7Sderaadt 		(void)printf("\nTie!\n");
330df930be7Sderaadt 	exit(0);
331df930be7Sderaadt }
332df930be7Sderaadt 
333995ddd3bSpjanzen void
printplayer(int player)3343eb8c9edSjsg printplayer(int player)
335df930be7Sderaadt {
336df930be7Sderaadt 	switch (player) {
337df930be7Sderaadt 	case COMPUTER:
338df930be7Sderaadt 		(void)printf("I ");
339df930be7Sderaadt 		break;
340df930be7Sderaadt 	case USER:
341df930be7Sderaadt 		(void)printf("You ");
342df930be7Sderaadt 		break;
343df930be7Sderaadt 	}
344df930be7Sderaadt }
345df930be7Sderaadt 
346995ddd3bSpjanzen void
printhand(const int * hand)3473eb8c9edSjsg printhand(const int *hand)
348df930be7Sderaadt {
3497faebae9Spjanzen 	int book, i, j;
350df930be7Sderaadt 
351df930be7Sderaadt 	for (book = i = 0; i < RANKS; i++)
352df930be7Sderaadt 		if (hand[i] < CARDS)
353df930be7Sderaadt 			for (j = hand[i]; --j >= 0;)
354df930be7Sderaadt 				PRC(i);
355df930be7Sderaadt 		else
356df930be7Sderaadt 			++book;
357df930be7Sderaadt 	if (book) {
358df930be7Sderaadt 		(void)printf(" + Book%s of", book > 1 ? "s" : "");
359df930be7Sderaadt 		for (i = 0; i < RANKS; i++)
360df930be7Sderaadt 			if (hand[i] == CARDS)
361df930be7Sderaadt 				PRC(i);
362df930be7Sderaadt 	}
363df930be7Sderaadt 	(void)putchar('\n');
364df930be7Sderaadt }
365df930be7Sderaadt 
366995ddd3bSpjanzen int
countcards(const int * hand)3673eb8c9edSjsg countcards(const int *hand)
368df930be7Sderaadt {
3697faebae9Spjanzen 	int i, count;
370df930be7Sderaadt 
371df930be7Sderaadt 	for (count = i = 0; i < RANKS; i++)
372df930be7Sderaadt 		count += *hand++;
373df930be7Sderaadt 	return(count);
374df930be7Sderaadt }
375df930be7Sderaadt 
376995ddd3bSpjanzen int
countbooks(const int * hand)3773eb8c9edSjsg countbooks(const int *hand)
378df930be7Sderaadt {
379df930be7Sderaadt 	int i, count;
380df930be7Sderaadt 
381df930be7Sderaadt 	for (count = i = 0; i < RANKS; i++)
382df930be7Sderaadt 		if (hand[i] == CARDS) {
383df930be7Sderaadt 			++count;
384df930be7Sderaadt 			PRC(i);
385df930be7Sderaadt 		}
386df930be7Sderaadt 	if (!count)
387df930be7Sderaadt 		(void)printf(" none");
388df930be7Sderaadt 	(void)putchar('\n');
389df930be7Sderaadt 	return(count);
390df930be7Sderaadt }
391df930be7Sderaadt 
392995ddd3bSpjanzen void
init(void)3933eb8c9edSjsg init(void)
394df930be7Sderaadt {
395c61e1f0cSpjanzen 	int i, j, temp;
396df930be7Sderaadt 
397c61e1f0cSpjanzen 	curcard = TOTCARDS;
398c61e1f0cSpjanzen 	for (i = 0; i < TOTCARDS; ++i)
399c61e1f0cSpjanzen 		deck[i] = i % RANKS;
400c61e1f0cSpjanzen 	for (i = 0; i < TOTCARDS - 1; ++i) {
401c61e1f0cSpjanzen 		j = nrandom(TOTCARDS-i);
402c61e1f0cSpjanzen 		if (j == 0)
403c61e1f0cSpjanzen 			continue;
404c61e1f0cSpjanzen 		temp = deck[i];
405c61e1f0cSpjanzen 		deck[i] = deck[i+j];
406c61e1f0cSpjanzen 		deck[i+j] = temp;
407df930be7Sderaadt 	}
408df930be7Sderaadt 	for (i = 0; i < HANDSIZE; ++i) {
409c61e1f0cSpjanzen 		++userhand[deck[--curcard]];
410c61e1f0cSpjanzen 		++comphand[deck[--curcard]];
411df930be7Sderaadt 	}
412df930be7Sderaadt }
413df930be7Sderaadt 
414995ddd3bSpjanzen int
nrandom(int n)4153eb8c9edSjsg nrandom(int n)
416df930be7Sderaadt {
41766e49541Snaddy 	return(arc4random_uniform(n));
418df930be7Sderaadt }
419df930be7Sderaadt 
42096b46b10Spjanzen int
getans(const char * prompt)4213eb8c9edSjsg getans(const char *prompt)
42296b46b10Spjanzen {
42396b46b10Spjanzen 	char buf[20];
42496b46b10Spjanzen 
42596b46b10Spjanzen 	/*
42696b46b10Spjanzen 	 * simple routine to ask the yes/no question specified until the user
42796b46b10Spjanzen 	 * answers yes or no, then return 1 if they said 'yes' and 0 if they
42896b46b10Spjanzen 	 * answered 'no'.
42996b46b10Spjanzen 	 */
43096b46b10Spjanzen 	for (;;) {
43196b46b10Spjanzen 		(void)printf("%s", prompt);
43296b46b10Spjanzen 		(void)fflush(stdout);
43363a9a751Spjanzen 		if (!fgets(buf, sizeof(buf), stdin)) {
43463a9a751Spjanzen 			(void)printf("\n");
43563a9a751Spjanzen 			exit(0);
43663a9a751Spjanzen 		}
43796b46b10Spjanzen 		if (*buf == 'N' || *buf == 'n')
43896b46b10Spjanzen 			return(0);
43996b46b10Spjanzen 		if (*buf == 'Y' || *buf == 'y')
44096b46b10Spjanzen 			return(1);
44196b46b10Spjanzen 		(void)printf(
44296b46b10Spjanzen "I don't understand your answer; please enter 'y' or 'n'!\n");
44396b46b10Spjanzen 	}
44496b46b10Spjanzen }
44596b46b10Spjanzen 
446995ddd3bSpjanzen void
instructions(void)4473eb8c9edSjsg instructions(void)
448df930be7Sderaadt {
44996b46b10Spjanzen 	const char *pager;
45096b46b10Spjanzen 	pid_t pid;
45196b46b10Spjanzen 	int status;
452df930be7Sderaadt 	int input;
45396b46b10Spjanzen 	int fd;
454df930be7Sderaadt 
45596b46b10Spjanzen 	if (getans("Would you like instructions (y or n)? ") == 0)
456df930be7Sderaadt 		return;
457df930be7Sderaadt 
45896b46b10Spjanzen 	if ((fd = open(_PATH_INSTR, O_RDONLY)) == -1)
45996b46b10Spjanzen 		(void)printf("No instruction file found!\n");
46096b46b10Spjanzen 	else {
46196b46b10Spjanzen 		switch (pid = fork()) {
46296b46b10Spjanzen 		case 0: /* child */
46396b46b10Spjanzen 			if (!isatty(1))
46496b46b10Spjanzen 				pager = "/bin/cat";
46596b46b10Spjanzen 			else {
46696b46b10Spjanzen 				if (!(pager = getenv("PAGER")) || (*pager == 0))
46796b46b10Spjanzen 					pager = _PATH_MORE;
46896b46b10Spjanzen 			}
46996b46b10Spjanzen 			if (dup2(fd, 0) == -1)
47096b46b10Spjanzen 				err(1, "dup2");
471c96f6a27Sderaadt 			(void)execl(_PATH_BSHELL, "sh", "-c", pager, (char *)NULL);
47296b46b10Spjanzen 			err(1, "exec sh -c %s", pager);
47396b46b10Spjanzen 			/* NOT REACHED */
47496b46b10Spjanzen 		case -1:
47596b46b10Spjanzen 			err(1, "fork");
47696b46b10Spjanzen 			/* NOT REACHED */
47796b46b10Spjanzen 		default:
47896b46b10Spjanzen 			(void)waitpid(pid, &status, 0);
47996b46b10Spjanzen 			close(fd);
48096b46b10Spjanzen 			break;
48196b46b10Spjanzen 		}
48296b46b10Spjanzen 	}
48396b46b10Spjanzen 
484df930be7Sderaadt 	(void)printf("Hit return to continue...\n");
485df930be7Sderaadt 	while ((input = getchar()) != EOF && input != '\n');
486df930be7Sderaadt }
487df930be7Sderaadt 
488995ddd3bSpjanzen void
usage(void)4893eb8c9edSjsg usage(void)
490df930be7Sderaadt {
491*6fa5e1daSmestre 	(void)fprintf(stderr, "usage: %s [-p]\n", getprogname());
492df930be7Sderaadt 	exit(1);
493df930be7Sderaadt }
494