xref: /netbsd-src/games/hack/hack.pager.c (revision acae68523ef8a8a415c9a13083ae0c636fb61bcd)
1*acae6852Splunky /*	$NetBSD: hack.pager.c,v 1.21 2011/09/01 07:18:50 plunky Exp $	*/
23ea4a95cSchristos 
3210cab45Smycroft /*
41c7f94e5Sjsm  * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
51c7f94e5Sjsm  * Amsterdam
61c7f94e5Sjsm  * All rights reserved.
71c7f94e5Sjsm  *
81c7f94e5Sjsm  * Redistribution and use in source and binary forms, with or without
91c7f94e5Sjsm  * modification, are permitted provided that the following conditions are
101c7f94e5Sjsm  * met:
111c7f94e5Sjsm  *
121c7f94e5Sjsm  * - Redistributions of source code must retain the above copyright notice,
131c7f94e5Sjsm  * this list of conditions and the following disclaimer.
141c7f94e5Sjsm  *
151c7f94e5Sjsm  * - Redistributions in binary form must reproduce the above copyright
161c7f94e5Sjsm  * notice, this list of conditions and the following disclaimer in the
171c7f94e5Sjsm  * documentation and/or other materials provided with the distribution.
181c7f94e5Sjsm  *
191c7f94e5Sjsm  * - Neither the name of the Stichting Centrum voor Wiskunde en
201c7f94e5Sjsm  * Informatica, nor the names of its contributors may be used to endorse or
211c7f94e5Sjsm  * promote products derived from this software without specific prior
221c7f94e5Sjsm  * written permission.
231c7f94e5Sjsm  *
241c7f94e5Sjsm  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
251c7f94e5Sjsm  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
261c7f94e5Sjsm  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
271c7f94e5Sjsm  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
281c7f94e5Sjsm  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
291c7f94e5Sjsm  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
301c7f94e5Sjsm  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
311c7f94e5Sjsm  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
321c7f94e5Sjsm  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
331c7f94e5Sjsm  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
341c7f94e5Sjsm  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
351c7f94e5Sjsm  */
361c7f94e5Sjsm 
371c7f94e5Sjsm /*
381c7f94e5Sjsm  * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
391c7f94e5Sjsm  * All rights reserved.
401c7f94e5Sjsm  *
411c7f94e5Sjsm  * Redistribution and use in source and binary forms, with or without
421c7f94e5Sjsm  * modification, are permitted provided that the following conditions
431c7f94e5Sjsm  * are met:
441c7f94e5Sjsm  * 1. Redistributions of source code must retain the above copyright
451c7f94e5Sjsm  *    notice, this list of conditions and the following disclaimer.
461c7f94e5Sjsm  * 2. Redistributions in binary form must reproduce the above copyright
471c7f94e5Sjsm  *    notice, this list of conditions and the following disclaimer in the
481c7f94e5Sjsm  *    documentation and/or other materials provided with the distribution.
491c7f94e5Sjsm  * 3. The name of the author may not be used to endorse or promote products
501c7f94e5Sjsm  *    derived from this software without specific prior written permission.
511c7f94e5Sjsm  *
521c7f94e5Sjsm  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
531c7f94e5Sjsm  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
541c7f94e5Sjsm  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
551c7f94e5Sjsm  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
561c7f94e5Sjsm  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
571c7f94e5Sjsm  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
581c7f94e5Sjsm  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
591c7f94e5Sjsm  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
601c7f94e5Sjsm  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
611c7f94e5Sjsm  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62210cab45Smycroft  */
63210cab45Smycroft 
643ea4a95cSchristos #include <sys/cdefs.h>
65210cab45Smycroft #ifndef lint
66*acae6852Splunky __RCSID("$NetBSD: hack.pager.c,v 1.21 2011/09/01 07:18:50 plunky Exp $");
67210cab45Smycroft #endif				/* not lint */
6861f28255Scgd 
6961f28255Scgd /* This file contains the command routine dowhatis() and a pager. */
703ea4a95cSchristos /*
713ea4a95cSchristos  * Also readmail() and doshell(), and generally the things that contact the
723ea4a95cSchristos  * outside world.
733ea4a95cSchristos  */
7461f28255Scgd 
7561f28255Scgd #include <sys/types.h>
76842dc544Sdholland #include <sys/wait.h>
77e6371e01Sjtc #include <signal.h>
78e6371e01Sjtc #include <stdlib.h>
79e6371e01Sjtc #include <unistd.h>
8061f28255Scgd #include "hack.h"
813ea4a95cSchristos #include "extern.h"
8261f28255Scgd 
839b92b189Sdholland static void intruph(int);
849b92b189Sdholland static void page_more(FILE *, int);
859b92b189Sdholland static int page_file(const char *, boolean);
869b92b189Sdholland static int child(int);
879b92b189Sdholland 
883ea4a95cSchristos int
dowhatis(void)891fa8a9a6Sdholland dowhatis(void)
9061f28255Scgd {
9161f28255Scgd 	FILE           *fp;
9261f28255Scgd 	char            bufr[BUFSZ + 6];
933ea4a95cSchristos 	char           *buf = &bufr[6], *ep, q;
9461f28255Scgd 
9561f28255Scgd 	if (!(fp = fopen(DATAFILE, "r")))
9661f28255Scgd 		pline("Cannot open data file!");
9761f28255Scgd 	else {
9861f28255Scgd 		pline("Specify what? ");
9961f28255Scgd 		q = readchar();
10061f28255Scgd 		if (q != '\t')
10161f28255Scgd 			while (fgets(buf, BUFSZ, fp))
10261f28255Scgd 				if (*buf == q) {
1033ea4a95cSchristos 					ep = strchr(buf, '\n');
1043ea4a95cSchristos 					if (ep)
1053ea4a95cSchristos 						*ep = 0;
10661f28255Scgd 					/* else: bad data file */
107db7b70f4Sjnemeth 					else {
108db7b70f4Sjnemeth 						pline("Bad data file!");
1098710461aSchristos 						(void) fclose(fp);
110db7b70f4Sjnemeth 						return(0);
111db7b70f4Sjnemeth 					}
11261f28255Scgd 					/* Expand tab 'by hand' */
11361f28255Scgd 					if (buf[1] == '\t') {
11461f28255Scgd 						buf = bufr;
11561f28255Scgd 						buf[0] = q;
11661f28255Scgd 						(void) strncpy(buf + 1, "       ", 7);
11761f28255Scgd 					}
11857c13365Sjoerg 					pline("%s", buf);
11961f28255Scgd 					if (ep[-1] == ';') {
12061f28255Scgd 						pline("More info? ");
12161f28255Scgd 						if (readchar() == 'y') {
12261f28255Scgd 							page_more(fp, 1);	/* does fclose() */
12361f28255Scgd 							return (0);
12461f28255Scgd 						}
12561f28255Scgd 					}
12661f28255Scgd 					(void) fclose(fp);	/* kopper@psuvax1 */
12761f28255Scgd 					return (0);
12861f28255Scgd 				}
12961f28255Scgd 		pline("I've never heard of such things.");
13061f28255Scgd 		(void) fclose(fp);
13161f28255Scgd 	}
13261f28255Scgd 	return (0);
13361f28255Scgd }
13461f28255Scgd 
13561f28255Scgd /* make the paging of a file interruptible */
13661f28255Scgd static int      got_intrup;
13761f28255Scgd 
1389b92b189Sdholland static void
intruph(int n __unused)1391fa8a9a6Sdholland intruph(int n __unused)
1403ea4a95cSchristos {
14161f28255Scgd 	got_intrup++;
14261f28255Scgd }
14361f28255Scgd 
14461f28255Scgd /* simple pager, also used from dohelp() */
1451fa8a9a6Sdholland /* strip: nr of chars to be stripped from each line (0 or 1) */
1469b92b189Sdholland static void
page_more(FILE * fp,int strip)1471fa8a9a6Sdholland page_more(FILE *fp, int strip)
14861f28255Scgd {
1493ea4a95cSchristos 	char           *bufr, *ep;
15061f28255Scgd 	sig_t           prevsig = signal(SIGINT, intruph);
15161f28255Scgd 
15261f28255Scgd 	set_pager(0);
153434d266eSdholland 	bufr = alloc(CO);
15461f28255Scgd 	bufr[CO - 1] = 0;
15561f28255Scgd 	while (fgets(bufr, CO - 1, fp) && (!strip || *bufr == '\t') && !got_intrup) {
1563ea4a95cSchristos 		ep = strchr(bufr, '\n');
15761f28255Scgd 		if (ep)
15861f28255Scgd 			*ep = 0;
15961f28255Scgd 		if (page_line(bufr + strip)) {
16061f28255Scgd 			set_pager(2);
16161f28255Scgd 			goto ret;
16261f28255Scgd 		}
16361f28255Scgd 	}
16461f28255Scgd 	set_pager(1);
16561f28255Scgd ret:
16661f28255Scgd 	free(bufr);
16761f28255Scgd 	(void) fclose(fp);
16861f28255Scgd 	(void) signal(SIGINT, prevsig);
16961f28255Scgd 	got_intrup = 0;
17061f28255Scgd }
17161f28255Scgd 
17261f28255Scgd static boolean  whole_screen = TRUE;
1733ea4a95cSchristos #define	PAGMIN	12		/* minimum # of lines for page below level
1743ea4a95cSchristos 				 * map */
17561f28255Scgd 
1763ea4a95cSchristos void
set_whole_screen(void)1771fa8a9a6Sdholland set_whole_screen(void)
1783ea4a95cSchristos {				/* called in termcap as soon as LI is known */
17961f28255Scgd 	whole_screen = (LI - ROWNO - 2 <= PAGMIN || !CD);
18061f28255Scgd }
18161f28255Scgd 
18261f28255Scgd #ifdef NEWS
1833ea4a95cSchristos int
readnews(void)1841fa8a9a6Sdholland readnews(void)
1853ea4a95cSchristos {
1863ea4a95cSchristos 	int             ret;
18761f28255Scgd 
18861f28255Scgd 	whole_screen = TRUE;	/* force a docrt(), our first */
18961f28255Scgd 	ret = page_file(NEWS, TRUE);
19061f28255Scgd 	set_whole_screen();
19161f28255Scgd 	return (ret);		/* report whether we did docrt() */
19261f28255Scgd }
1933ea4a95cSchristos #endif	/* NEWS */
19461f28255Scgd 
1951fa8a9a6Sdholland /* mode:  0: open  1: wait+close  2: close */
1963ea4a95cSchristos void
set_pager(int mode)1971fa8a9a6Sdholland set_pager(int mode)
19861f28255Scgd {
19961f28255Scgd 	static boolean  so;
20061f28255Scgd 	if (mode == 0) {
20161f28255Scgd 		if (!whole_screen) {
20261f28255Scgd 			/* clear topline */
20361f28255Scgd 			clrlin();
20461f28255Scgd 			/* use part of screen below level map */
20561f28255Scgd 			curs(1, ROWNO + 4);
20661f28255Scgd 		} else {
20761f28255Scgd 			cls();
20861f28255Scgd 		}
20961f28255Scgd 		so = flags.standout;
21061f28255Scgd 		flags.standout = 1;
21161f28255Scgd 	} else {
21261f28255Scgd 		if (mode == 1) {
21361f28255Scgd 			curs(1, LI);
21461f28255Scgd 			more();
21561f28255Scgd 		}
21661f28255Scgd 		flags.standout = so;
21761f28255Scgd 		if (whole_screen)
21861f28255Scgd 			docrt();
21961f28255Scgd 		else {
22061f28255Scgd 			curs(1, ROWNO + 4);
22161f28255Scgd 			cl_eos();
22261f28255Scgd 		}
22361f28255Scgd 	}
22461f28255Scgd }
22561f28255Scgd 
2263ea4a95cSchristos int
page_line(const char * s)2271fa8a9a6Sdholland page_line(const char *s)	/* returns 1 if we should quit */
22861f28255Scgd {
22961f28255Scgd 	if (cury == LI - 1) {
23061f28255Scgd 		if (!*s)
23161f28255Scgd 			return (0);	/* suppress blank lines at top */
23261f28255Scgd 		putchar('\n');
23361f28255Scgd 		cury++;
23461f28255Scgd 		cmore("q\033");
23561f28255Scgd 		if (morc) {
23661f28255Scgd 			morc = 0;
23761f28255Scgd 			return (1);
23861f28255Scgd 		}
23961f28255Scgd 		if (whole_screen)
24061f28255Scgd 			cls();
24161f28255Scgd 		else {
24261f28255Scgd 			curs(1, ROWNO + 4);
24361f28255Scgd 			cl_eos();
24461f28255Scgd 		}
24561f28255Scgd 	}
24661f28255Scgd 	puts(s);
24761f28255Scgd 	cury++;
24861f28255Scgd 	return (0);
24961f28255Scgd }
25061f28255Scgd 
25161f28255Scgd /*
25261f28255Scgd  * Flexible pager: feed it with a number of lines and it will decide
25361f28255Scgd  * whether these should be fed to the pager above, or displayed in a
25461f28255Scgd  * corner.
25561f28255Scgd  * Call:
25661f28255Scgd  *	cornline(0, title or 0)	: initialize
25761f28255Scgd  *	cornline(1, text)	: add text to the chain of texts
25861f28255Scgd  *	cornline(2, morcs)	: output everything and cleanup
25961f28255Scgd  *	cornline(3, 0)		: cleanup
26061f28255Scgd  */
26161f28255Scgd 
2623ea4a95cSchristos void
cornline(int mode,const char * text)2631fa8a9a6Sdholland cornline(int mode, const char *text)
26461f28255Scgd {
26561f28255Scgd 	static struct line {
26661f28255Scgd 		struct line    *next_line;
26761f28255Scgd 		char           *line_text;
26861f28255Scgd 	}              *texthead, *texttail;
26961f28255Scgd 	static int      maxlen;
27061f28255Scgd 	static int      linect;
2713ea4a95cSchristos 	struct line    *tl;
27261f28255Scgd 
27361f28255Scgd 	if (mode == 0) {
27461f28255Scgd 		texthead = 0;
27561f28255Scgd 		maxlen = 0;
27661f28255Scgd 		linect = 0;
27761f28255Scgd 		if (text) {
27861f28255Scgd 			cornline(1, text);	/* title */
27961f28255Scgd 			cornline(1, "");	/* blank line */
28061f28255Scgd 		}
28161f28255Scgd 		return;
28261f28255Scgd 	}
28361f28255Scgd 	if (mode == 1) {
2843ea4a95cSchristos 		int             len;
28561f28255Scgd 
2863ea4a95cSchristos 		if (!text)
2873ea4a95cSchristos 			return;	/* superfluous, just to be sure */
28861f28255Scgd 		linect++;
28961f28255Scgd 		len = strlen(text);
29061f28255Scgd 		if (len > maxlen)
29161f28255Scgd 			maxlen = len;
292434d266eSdholland 		tl = alloc(len + sizeof(*tl) + 1);
29361f28255Scgd 		tl->next_line = 0;
29461f28255Scgd 		tl->line_text = (char *) (tl + 1);
29561f28255Scgd 		(void) strcpy(tl->line_text, text);
29661f28255Scgd 		if (!texthead)
29761f28255Scgd 			texthead = tl;
29861f28255Scgd 		else
29961f28255Scgd 			texttail->next_line = tl;
30061f28255Scgd 		texttail = tl;
30161f28255Scgd 		return;
30261f28255Scgd 	}
30361f28255Scgd 	/* --- now we really do it --- */
30461f28255Scgd 	if (mode == 2 && linect == 1)	/* topline only */
30557c13365Sjoerg 		pline("%s", texthead->line_text);
3063ea4a95cSchristos 	else if (mode == 2) {
3073ea4a95cSchristos 		int             curline, lth;
30861f28255Scgd 
3093ea4a95cSchristos 		if (flags.toplin == 1)
3103ea4a95cSchristos 			more();	/* ab@unido */
31161f28255Scgd 		remember_topl();
31261f28255Scgd 
31361f28255Scgd 		lth = CO - maxlen - 2;	/* Use full screen width */
31461f28255Scgd 		if (linect < LI && lth >= 10) {	/* in a corner */
31561f28255Scgd 			home();
31661f28255Scgd 			cl_end();
31761f28255Scgd 			flags.toplin = 0;
31861f28255Scgd 			curline = 1;
31961f28255Scgd 			for (tl = texthead; tl; tl = tl->next_line) {
32061f28255Scgd 				curs(lth, curline);
32161f28255Scgd 				if (curline > 1)
32261f28255Scgd 					cl_end();
32361f28255Scgd 				putsym(' ');
32461f28255Scgd 				putstr(tl->line_text);
32561f28255Scgd 				curline++;
32661f28255Scgd 			}
32761f28255Scgd 			curs(lth, curline);
32861f28255Scgd 			cl_end();
32961f28255Scgd 			cmore(text);
33061f28255Scgd 			home();
33161f28255Scgd 			cl_end();
33261f28255Scgd 			docorner(lth, curline - 1);
33361f28255Scgd 		} else {	/* feed to pager */
33461f28255Scgd 			set_pager(0);
33561f28255Scgd 			for (tl = texthead; tl; tl = tl->next_line) {
33661f28255Scgd 				if (page_line(tl->line_text)) {
33761f28255Scgd 					set_pager(2);
33861f28255Scgd 					goto cleanup;
33961f28255Scgd 				}
34061f28255Scgd 			}
34161f28255Scgd 			if (text) {
34261f28255Scgd 				cgetret(text);
34361f28255Scgd 				set_pager(2);
34461f28255Scgd 			} else
34561f28255Scgd 				set_pager(1);
34661f28255Scgd 		}
34761f28255Scgd 	}
34861f28255Scgd cleanup:
3493ea4a95cSchristos 	while ((tl = texthead) != NULL) {
35061f28255Scgd 		texthead = tl->next_line;
3518e73b3adSdholland 		free(tl);
35261f28255Scgd 	}
35361f28255Scgd }
35461f28255Scgd 
3553ea4a95cSchristos int
dohelp(void)3561fa8a9a6Sdholland dohelp(void)
35761f28255Scgd {
35861f28255Scgd 	char            c;
35961f28255Scgd 
36061f28255Scgd 	pline("Long or short help? ");
3613ea4a95cSchristos 	while (((c = readchar()) != 'l') && (c != 's') && !strchr(quitchars, c))
36298eb8895Sroy 		sound_bell();
3633ea4a95cSchristos 	if (!strchr(quitchars, c))
36461f28255Scgd 		(void) page_file((c == 'l') ? HELP : SHELP, FALSE);
36561f28255Scgd 	return (0);
36661f28255Scgd }
36761f28255Scgd 
3681fa8a9a6Sdholland /* return: 0 - cannot open fnam; 1 - otherwise */
3699b92b189Sdholland static int
page_file(const char * fnam,boolean silent)3701fa8a9a6Sdholland page_file(const char *fnam, boolean silent)
37161f28255Scgd {
37261f28255Scgd #ifdef DEF_PAGER		/* this implies that UNIX is defined */
37361f28255Scgd 	{
37461f28255Scgd 		/* use external pager; this may give security problems */
37561f28255Scgd 
376ab8b6343Sjsm 		int             fd = open(fnam, O_RDONLY);
37761f28255Scgd 
37861f28255Scgd 		if (fd < 0) {
3793ea4a95cSchristos 			if (!silent)
3803ea4a95cSchristos 				pline("Cannot open %s.", fnam);
38161f28255Scgd 			return (0);
38261f28255Scgd 		}
38361f28255Scgd 		if (child(1)) {
38461f28255Scgd 
3853ea4a95cSchristos 			/*
3863ea4a95cSchristos 			 * Now that child() does a setuid(getuid()) and a
3873ea4a95cSchristos 			 * chdir(), we may not be able to open file fnam
3883ea4a95cSchristos 			 * anymore, so make it stdin.
3893ea4a95cSchristos 			 */
39061f28255Scgd 			(void) close(0);
39161f28255Scgd 			if (dup(fd)) {
3923ea4a95cSchristos 				if (!silent)
3933ea4a95cSchristos 					printf("Cannot open %s as stdin.\n", fnam);
39461f28255Scgd 			} else {
395*acae6852Splunky 				execl(catmore, "page", (char *)NULL);
3963ea4a95cSchristos 				if (!silent)
3973ea4a95cSchristos 					printf("Cannot exec %s.\n", catmore);
39861f28255Scgd 			}
39961f28255Scgd 			exit(1);
40061f28255Scgd 		}
40161f28255Scgd 		(void) close(fd);
40261f28255Scgd 	}
4033ea4a95cSchristos #else	/* DEF_PAGER */
40461f28255Scgd 	{
40561f28255Scgd 		FILE           *f;	/* free after Robert Viduya */
40661f28255Scgd 
40761f28255Scgd 		if ((f = fopen(fnam, "r")) == (FILE *) 0) {
40861f28255Scgd 			if (!silent) {
4093ea4a95cSchristos 				home();
4103ea4a95cSchristos 				perror(fnam);
4113ea4a95cSchristos 				flags.toplin = 1;
41261f28255Scgd 				pline("Cannot open %s.", fnam);
41361f28255Scgd 			}
41461f28255Scgd 			return (0);
41561f28255Scgd 		}
41661f28255Scgd 		page_more(f, 0);
41761f28255Scgd 	}
4183ea4a95cSchristos #endif	/* DEF_PAGER */
41961f28255Scgd 
42061f28255Scgd 	return (1);
42161f28255Scgd }
42261f28255Scgd 
42361f28255Scgd #ifdef UNIX
42461f28255Scgd #ifdef SHELL
4253ea4a95cSchristos int
dosh(void)4261fa8a9a6Sdholland dosh(void)
4273ea4a95cSchristos {
4283ea4a95cSchristos 	char           *str;
42961f28255Scgd 	if (child(0)) {
4303ea4a95cSchristos 		if ((str = getenv("SHELL")) != NULL)
431*acae6852Splunky 			execl(str, str, (char *)NULL);
43261f28255Scgd 		else
433*acae6852Splunky 			execl("/bin/sh", "sh", (char *)NULL);
43461f28255Scgd 		pline("sh: cannot execute.");
43561f28255Scgd 		exit(1);
43661f28255Scgd 	}
43761f28255Scgd 	return (0);
43861f28255Scgd }
4393ea4a95cSchristos #endif	/* SHELL */
44061f28255Scgd 
4419b92b189Sdholland static int
child(int wt)442ab8b6343Sjsm child(int wt)
4433ea4a95cSchristos {
44461f28255Scgd 	int             status;
4453ea4a95cSchristos 	int             f;
44661f28255Scgd 
44761f28255Scgd 	f = fork();
44861f28255Scgd 	if (f == 0) {		/* child */
4492c0ecb1aSdholland 		settty(NULL);	/* also calls end_screen() */
45061f28255Scgd 		(void) setuid(getuid());
45161f28255Scgd 		(void) setgid(getgid());
45261f28255Scgd #ifdef CHDIR
45361f28255Scgd 		(void) chdir(getenv("HOME"));
4543ea4a95cSchristos #endif	/* CHDIR */
45561f28255Scgd 		return (1);
45661f28255Scgd 	}
45761f28255Scgd 	if (f == -1) {		/* cannot fork */
45861f28255Scgd 		pline("Fork failed. Try again.");
45961f28255Scgd 		return (0);
46061f28255Scgd 	}
46161f28255Scgd 	/* fork succeeded; wait for child to exit */
46261f28255Scgd 	(void) signal(SIGINT, SIG_IGN);
46361f28255Scgd 	(void) signal(SIGQUIT, SIG_IGN);
46461f28255Scgd 	(void) wait(&status);
46561f28255Scgd 	gettty();
46661f28255Scgd 	setftty();
46761f28255Scgd 	(void) signal(SIGINT, done1);
46861f28255Scgd #ifdef WIZARD
4693ea4a95cSchristos 	if (wizard)
4703ea4a95cSchristos 		(void) signal(SIGQUIT, SIG_DFL);
4713ea4a95cSchristos #endif	/* WIZARD */
4723ea4a95cSchristos 	if (wt)
4733ea4a95cSchristos 		getret();
47461f28255Scgd 	docrt();
47561f28255Scgd 	return (0);
47661f28255Scgd }
4773ea4a95cSchristos #endif	/* UNIX */
478