xref: /csrg-svn/old/init/init.c (revision 42407)
121135Sdist /*
228801Skarels  * Copyright (c) 1980,1986 Regents of the University of California.
321135Sdist  * All rights reserved.  The Berkeley software License Agreement
421135Sdist  * specifies the terms and conditions for redistribution.
521135Sdist  */
621135Sdist 
712682Ssam #ifndef lint
8*42407Smarc static char sccsid[] = "@(#)init.c	5.15 (Berkeley) 05/27/90";
921135Sdist #endif not lint
1012682Ssam 
111029Sbill #include <sys/types.h>
1237284Sbostic #include <sys/file.h>
1337284Sbostic #include <sys/signal.h>
1437284Sbostic #include <sys/reboot.h>
1537284Sbostic #include <sys/syslog.h>
1637284Sbostic #include <sys/stat.h>
17*42407Smarc #include <sys/ioctl.h>
181029Sbill #include <setjmp.h>
1935606Sbostic #include <utmp.h>
202821Swnj #include <errno.h>
2116452Sroot #include <ttyent.h>
2237284Sbostic #include "pathnames.h"
231029Sbill 
2424494Skarels #define	CMDSIZ	200	/* max string length for getty or window command*/
2523147Sbloom #define	ALL	p = itab; p ; p = p->next
261029Sbill #define	EVER	;;
271029Sbill #define SCPYN(a, b)	strncpy(a, b, sizeof(a))
281029Sbill #define SCMPN(a, b)	strncmp(a, b, sizeof(a))
291029Sbill 
3037284Sbostic char	shell[]	= _PATH_BSHELL;
311029Sbill char	minus[]	= "-";
3237284Sbostic char	runc[]	= _PATH_RC;
3337284Sbostic char	ctty[]	= _PATH_CONSOLE;
341029Sbill 
351029Sbill struct	tab
361029Sbill {
3735670Sbostic 	char	line[UT_LINESIZE];
3818542Sralph 	char	comn[CMDSIZ];
391029Sbill 	char	xflag;
401029Sbill 	int	pid;
4118542Sralph 	int	wpid;		/* window system pid for SIGHUP	*/
4218542Sralph 	char	wcmd[CMDSIZ];	/* command to start window system process */
435971Sroot 	time_t	gettytime;
445971Sroot 	int	gettycnt;
4522181Skarels 	time_t	windtime;
4622181Skarels 	int	windcnt;
4723147Sbloom 	struct	tab *next;
4823147Sbloom } *itab;
491029Sbill 
501029Sbill int	fi;
511029Sbill int	mergflag;
521029Sbill char	tty[20];
531429Sbill jmp_buf	sjbuf, shutpass;
541029Sbill 
551029Sbill char	*strcpy(), *strcat();
561029Sbill long	lseek();
57*42407Smarc void	idle(), merge(), reset();
581029Sbill 
5918542Sralph struct	sigvec rvec = { reset, sigmask(SIGHUP), 0 };
6013021Ssam 
6129836Ssam #if defined(vax) || defined(tahoe)
621029Sbill main()
631029Sbill {
6429836Ssam #if defined(tahoe)
6529836Ssam 	register int r12;		/* make sure r11 gets bootflags */
6629836Ssam #endif
671403Sbill 	register int r11;		/* passed thru from boot */
6813021Ssam #else
699869Spugs main(argc, argv)
709869Spugs 	char **argv;
719869Spugs {
7213021Ssam #endif
73*42407Smarc 	int howto, oldhowto, started;
741403Sbill 
7529836Ssam #if defined(vax) || defined(tahoe)
761403Sbill 	howto = r11;
7713021Ssam #else
78*42407Smarc 	howto = 0;
799869Spugs 	if (argc > 1 && argv[1][0] == '-') {
809869Spugs 		char *cp;
819869Spugs 
829869Spugs 		cp = &argv[1][1];
839869Spugs 		while (*cp) switch (*cp++) {
849869Spugs 		case 'a':
859869Spugs 			howto |= RB_ASKNAME;
869869Spugs 			break;
879869Spugs 		case 's':
889869Spugs 			howto |= RB_SINGLE;
899869Spugs 			break;
909869Spugs 		}
919869Spugs 	} else {
929869Spugs 		howto = RB_SINGLE;
939869Spugs 	}
9413021Ssam #endif
95*42407Smarc 	if (getuid() != 0)
96*42407Smarc 		exit(1);
9724854Seric 	openlog("init", LOG_CONS|LOG_ODELAY, LOG_AUTH);
98*42407Smarc 	if (setsid() < 0)
99*42407Smarc 		syslog(LOG_ERR, "setsid failed (initial) %m");
10013021Ssam 	sigvec(SIGTERM, &rvec, (struct sigvec *)0);
1012821Swnj 	signal(SIGTSTP, idle);
1021029Sbill 	signal(SIGSTOP, SIG_IGN);
1031029Sbill 	signal(SIGTTIN, SIG_IGN);
1041029Sbill 	signal(SIGTTOU, SIG_IGN);
10513021Ssam 	(void) setjmp(sjbuf);
106*42407Smarc 	for (started = 0; ; ) {
1071403Sbill 		oldhowto = howto;
1081403Sbill 		howto = RB_SINGLE;
109*42407Smarc 		if (started && setjmp(shutpass) == 0)
1101429Sbill 			shutdown();
111*42407Smarc 		started = 1;
1121403Sbill 		if (oldhowto & RB_SINGLE)
1131403Sbill 			single();
1141403Sbill 		if (runcom(oldhowto) == 0)
1151403Sbill 			continue;
1161029Sbill 		merge();
1171029Sbill 		multiple();
1181029Sbill 	}
1191029Sbill }
1201029Sbill 
121*42407Smarc void	shutreset();
1221429Sbill 
1231029Sbill shutdown()
1241029Sbill {
1251029Sbill 	register i;
12623147Sbloom 	register struct tab *p, *p1;
1271029Sbill 
1281029Sbill 	signal(SIGHUP, SIG_IGN);
12923147Sbloom 	for (p = itab; p ; ) {
1301029Sbill 		term(p);
13123147Sbloom 		p1 = p->next;
13223147Sbloom 		free(p);
13323147Sbloom 		p = p1;
1341029Sbill 	}
13523147Sbloom 	itab = (struct tab *)0;
1361429Sbill 	signal(SIGALRM, shutreset);
13728801Skarels 	(void) kill(-1, SIGTERM);	/* one chance to catch it */
13828801Skarels 	sleep(5);
1391429Sbill 	alarm(30);
14013021Ssam 	for (i = 0; i < 5; i++)
1411029Sbill 		kill(-1, SIGKILL);
14213021Ssam 	while (wait((int *)0) != -1)
1431029Sbill 		;
1441029Sbill 	alarm(0);
1451429Sbill 	shutend();
1461429Sbill }
1471429Sbill 
148*42407Smarc char shutfailm[] = "init: WARNING: something is hung (won't die); ps axl advised\n";
1491429Sbill 
150*42407Smarc void
1511429Sbill shutreset()
1521429Sbill {
1531429Sbill 	int status;
1541429Sbill 
1551429Sbill 	if (fork() == 0) {
1561429Sbill 		int ct = open(ctty, 1);
1571429Sbill 		write(ct, shutfailm, sizeof (shutfailm));
1581429Sbill 		sleep(5);
1591429Sbill 		exit(1);
1601429Sbill 	}
1611429Sbill 	sleep(5);
1621429Sbill 	shutend();
1631429Sbill 	longjmp(shutpass, 1);
1641429Sbill }
1651429Sbill 
1661429Sbill shutend()
1671429Sbill {
1682821Swnj 	register i, f;
1691429Sbill 
1702821Swnj 	acct(0);
1711029Sbill 	signal(SIGALRM, SIG_DFL);
17213021Ssam 	for (i = 0; i < 10; i++)
1731029Sbill 		close(i);
17435606Sbostic 	logwtmp("~", "shutdown", "");
1751029Sbill }
1761029Sbill 
1771029Sbill single()
1781029Sbill {
1791029Sbill 	register pid;
1802821Swnj 	register xpid;
18135606Sbostic 	extern int errno;
1821029Sbill 
18313021Ssam 	do {
18413021Ssam 		pid = fork();
18513021Ssam 		if (pid == 0) {
18613021Ssam 			signal(SIGTERM, SIG_DFL);
18713021Ssam 			signal(SIGHUP, SIG_DFL);
18813021Ssam 			signal(SIGALRM, SIG_DFL);
18916452Sroot 			signal(SIGTSTP, SIG_IGN);
190*42407Smarc 			if (setsid() < 0)
191*42407Smarc 				syslog(LOG_ERR, "setsid failed (single): %m");
19213021Ssam 			(void) open(ctty, O_RDWR);
193*42407Smarc 			if (ioctl(0, TIOCSCTTY, 0) < 0)
194*42407Smarc 				syslog(LOG_ERR, "TIOCSCTTY failed: %m");
19513021Ssam 			dup2(0, 1);
19613021Ssam 			dup2(0, 2);
19713021Ssam 			execl(shell, minus, (char *)0);
19830516Sbostic 			perror(shell);
19913021Ssam 			exit(0);
20013021Ssam 		}
20113021Ssam 		while ((xpid = wait((int *)0)) != pid)
20213021Ssam 			if (xpid == -1 && errno == ECHILD)
20313021Ssam 				break;
20413021Ssam 	} while (xpid == -1);
2051029Sbill }
2061029Sbill 
2071403Sbill runcom(oldhowto)
2081403Sbill 	int oldhowto;
2091029Sbill {
2101029Sbill 	register pid, f;
2111403Sbill 	int status;
2121029Sbill 
2131029Sbill 	pid = fork();
21413021Ssam 	if (pid == 0) {
215*42407Smarc 		(void) open(ctty, O_RDONLY);
21613021Ssam 		dup2(0, 1);
21713021Ssam 		dup2(0, 2);
218*42407Smarc 		if (setsid() < 0)
219*42407Smarc 			syslog(LOG_ERR, "setsid failed (runcom) %m");
220*42407Smarc 		if (ioctl(0, TIOCSCTTY, 0) < 0)
221*42407Smarc 			syslog(LOG_ERR, "TIOCSCTTY failed (runcom) %m");
2221403Sbill 		if (oldhowto & RB_SINGLE)
2231403Sbill 			execl(shell, shell, runc, (char *)0);
2241403Sbill 		else
2251403Sbill 			execl(shell, shell, runc, "autoboot", (char *)0);
2261403Sbill 		exit(1);
2271029Sbill 	}
22813021Ssam 	while (wait(&status) != pid)
2291029Sbill 		;
23013021Ssam 	if (status)
23113021Ssam 		return (0);
23235606Sbostic 	logwtmp("~", "reboot", "");
23313021Ssam 	return (1);
2341029Sbill }
2351029Sbill 
23618542Sralph struct	sigvec	mvec = { merge, sigmask(SIGTERM), 0 };
23713021Ssam /*
23813021Ssam  * Multi-user.  Listen for users leaving, SIGHUP's
23913021Ssam  * which indicate ttys has changed, and SIGTERM's which
24013021Ssam  * are used to shutdown the system.
24113021Ssam  */
2421029Sbill multiple()
2431029Sbill {
244*42407Smarc 	extern int errno;
2451029Sbill 	register struct tab *p;
2461029Sbill 	register pid;
24723147Sbloom 	int omask;
2481029Sbill 
24913021Ssam 	sigvec(SIGHUP, &mvec, (struct sigvec *)0);
25013021Ssam 	for (EVER) {
2511029Sbill 		pid = wait((int *)0);
252*42407Smarc /* SHOULD FIX THIS IN THE KERNEL */
253*42407Smarc 		if (pid == -1 && errno != EINTR)
2541029Sbill 			return;
25530516Sbostic 		omask = sigblock(sigmask(SIGHUP));
25618542Sralph 		for (ALL) {
25718542Sralph 			/* must restart window system BEFORE emulator */
25818542Sralph 			if (p->wpid == pid || p->wpid == -1)
25918542Sralph 				wstart(p);
26013021Ssam 			if (p->pid == pid || p->pid == -1) {
26118542Sralph 				/* disown the window system */
26218542Sralph 				if (p->wpid)
26318542Sralph 					kill(p->wpid, SIGHUP);
26435445Sbostic 				cleanutmp(p);
2651029Sbill 				dfork(p);
2661029Sbill 			}
26718542Sralph 		}
26823147Sbloom 		sigsetmask(omask);
2691029Sbill 	}
2701029Sbill }
2711029Sbill 
27213021Ssam /*
27313021Ssam  * Merge current contents of ttys file
27413021Ssam  * into in-core table of configured tty lines.
27513021Ssam  * Entered as signal handler for SIGHUP.
27613021Ssam  */
27713021Ssam #define	FOUND	1
27813021Ssam #define	CHANGE	2
27918542Sralph #define WCHANGE 4
28013021Ssam 
281*42407Smarc void
28213021Ssam merge()
28313021Ssam {
28413021Ssam 	register struct tab *p;
28516452Sroot 	register struct ttyent *t;
28623147Sbloom 	register struct tab *p1;
28713021Ssam 
28813021Ssam 	for (ALL)
28913021Ssam 		p->xflag = 0;
29016452Sroot 	setttyent();
29116452Sroot 	while (t = getttyent()) {
29216452Sroot 		if ((t->ty_status & TTY_ON) == 0)
29316452Sroot 			continue;
29413021Ssam 		for (ALL) {
29516452Sroot 			if (SCMPN(p->line, t->ty_name))
29613021Ssam 				continue;
29713021Ssam 			p->xflag |= FOUND;
29816452Sroot 			if (SCMPN(p->comn, t->ty_getty)) {
29913021Ssam 				p->xflag |= CHANGE;
30016452Sroot 				SCPYN(p->comn, t->ty_getty);
30113021Ssam 			}
30230516Sbostic 			if (SCMPN(p->wcmd, t->ty_window ? t->ty_window : "")) {
30318542Sralph 				p->xflag |= WCHANGE|CHANGE;
30418542Sralph 				SCPYN(p->wcmd, t->ty_window);
30518542Sralph 			}
30613021Ssam 			goto contin1;
30713021Ssam 		}
30818542Sralph 
30923147Sbloom 		/*
31023147Sbloom 		 * Make space for a new one
31123147Sbloom 		 */
31223147Sbloom 		p1 = (struct tab *)calloc(1, sizeof(*p1));
31323147Sbloom 		if (!p1) {
31423147Sbloom 			syslog(LOG_ERR, "no space for '%s' !?!", t->ty_name);
31513021Ssam 			goto contin1;
31613021Ssam 		}
31723147Sbloom 		/*
31823147Sbloom 		 * Put new terminal at the end of the linked list.
31923147Sbloom 		 */
32023147Sbloom 		if (itab) {
32123147Sbloom 			for (p = itab; p->next ; p = p->next)
32223147Sbloom 				;
32323147Sbloom 			p->next = p1;
32423147Sbloom 		} else
32523147Sbloom 			itab = p1;
32623147Sbloom 
32723147Sbloom 		p = p1;
32823147Sbloom 		SCPYN(p->line, t->ty_name);
32923147Sbloom 		p->xflag |= FOUND|CHANGE;
33023147Sbloom 		SCPYN(p->comn, t->ty_getty);
33130516Sbostic 		if (t->ty_window && strcmp(t->ty_window, "") != 0) {
33223147Sbloom 			p->xflag |= WCHANGE;
33323147Sbloom 			SCPYN(p->wcmd, t->ty_window);
33423147Sbloom 		}
33513021Ssam 	contin1:
33613021Ssam 		;
33713021Ssam 	}
33816452Sroot 	endttyent();
33923147Sbloom 	p1 = (struct tab *)0;
34013021Ssam 	for (ALL) {
34113021Ssam 		if ((p->xflag&FOUND) == 0) {
34213021Ssam 			term(p);
34318542Sralph 			wterm(p);
34423147Sbloom 			if (p1)
34523147Sbloom 				p1->next = p->next;
34623147Sbloom 			else
34723147Sbloom 				itab = p->next;
34823147Sbloom 			free(p);
34923147Sbloom 			p = p1 ? p1 : itab;
35023147Sbloom 		} else {
35123147Sbloom 			/* window system should be started first */
35223147Sbloom 			if (p->xflag&WCHANGE) {
35323147Sbloom 				wterm(p);
35423147Sbloom 				wstart(p);
35523147Sbloom 			}
35623147Sbloom 			if (p->xflag&CHANGE) {
35723147Sbloom 				term(p);
35823147Sbloom 				dfork(p);
35923147Sbloom 			}
36013021Ssam 		}
36123147Sbloom 		p1 = p;
36213021Ssam 	}
36313021Ssam }
36413021Ssam 
3651029Sbill term(p)
36613021Ssam 	register struct tab *p;
3671029Sbill {
3681029Sbill 
36913021Ssam 	if (p->pid != 0) {
37035445Sbostic 		cleanutmp(p);
3711029Sbill 		kill(p->pid, SIGKILL);
3721029Sbill 	}
3731029Sbill 	p->pid = 0;
37418542Sralph 	/* send SIGHUP to get rid of connections */
37518542Sralph 	if (p->wpid > 0)
37618542Sralph 		kill(p->wpid, SIGHUP);
3771029Sbill }
3781029Sbill 
3791029Sbill dfork(p)
38013021Ssam 	struct tab *p;
3811029Sbill {
3821029Sbill 	register pid;
3835971Sroot 	time_t t;
3845971Sroot 	int dowait = 0;
3851029Sbill 
3865971Sroot 	time(&t);
3875971Sroot 	p->gettycnt++;
3885971Sroot 	if ((t - p->gettytime) >= 60) {
3895971Sroot 		p->gettytime = t;
3905971Sroot 		p->gettycnt = 1;
39118542Sralph 	} else if (p->gettycnt >= 5) {
39218542Sralph 		dowait = 1;
39318542Sralph 		p->gettytime = t;
39418542Sralph 		p->gettycnt = 1;
3955971Sroot 	}
3961029Sbill 	pid = fork();
39713021Ssam 	if (pid == 0) {
3986816Ssam 		signal(SIGTERM, SIG_DFL);
3996816Ssam 		signal(SIGHUP, SIG_IGN);
40022181Skarels 		sigsetmask(0);	/* since can be called from masked code */
4015971Sroot 		if (dowait) {
40218542Sralph 			syslog(LOG_ERR, "'%s %s' failing, sleeping", p->comn, p->line);
40318542Sralph 			closelog();
4045971Sroot 			sleep(30);
4055971Sroot 		}
406*42407Smarc 		if (setsid() < 0)
407*42407Smarc 			syslog(LOG_ERR, "setsid failed(dfork) %m");
40818542Sralph 		execit(p->comn, p->line);
4091029Sbill 		exit(0);
4101029Sbill 	}
4111029Sbill 	p->pid = pid;
4121029Sbill }
4131029Sbill 
41435445Sbostic cleanutmp(p)
41513021Ssam 	register struct tab *p;
4161029Sbill {
41735445Sbostic 	if (logout(p->line)) {
418*42407Smarc 		logwtmp(p->line, "", "");
41917582Ssam 		/*
42017582Ssam 		 * After a proper login force reset
42117582Ssam 		 * of error detection code in dfork.
42217582Ssam 		 */
42317582Ssam 		p->gettytime = 0;
42422181Skarels 		p->windtime = 0;
4251029Sbill 	}
4261029Sbill }
4271029Sbill 
428*42407Smarc void
4291029Sbill reset()
4301029Sbill {
4311029Sbill 	longjmp(sjbuf, 1);
4321029Sbill }
4332821Swnj 
43413021Ssam jmp_buf	idlebuf;
43513021Ssam 
436*42407Smarc void
43713021Ssam idlehup()
43813021Ssam {
43913021Ssam 	longjmp(idlebuf, 1);
44013021Ssam }
44113021Ssam 
442*42407Smarc void
4432821Swnj idle()
4442821Swnj {
4452821Swnj 	register struct tab *p;
4462821Swnj 	register pid;
4472821Swnj 
44813021Ssam 	signal(SIGHUP, idlehup);
44918542Sralph 	for (EVER) {
45013021Ssam 		if (setjmp(idlebuf))
45113021Ssam 			return;
4522821Swnj 		pid = wait((int *) 0);
45313021Ssam 		if (pid == -1) {
45413021Ssam 			sigpause(0);
45513021Ssam 			continue;
4562821Swnj 		}
45718542Sralph 		for (ALL) {
45818542Sralph 			/* if window system dies, mark it for restart */
45918542Sralph 			if (p->wpid == pid)
46018542Sralph 				p->wpid = -1;
46113021Ssam 			if (p->pid == pid) {
46235445Sbostic 				cleanutmp(p);
46313021Ssam 				p->pid = -1;
46413021Ssam 			}
46518542Sralph 		}
4662821Swnj 	}
4672821Swnj }
46818542Sralph 
46918542Sralph wterm(p)
47018542Sralph 	register struct tab *p;
47118542Sralph {
47218542Sralph 	if (p->wpid != 0) {
47318542Sralph 		kill(p->wpid, SIGKILL);
47418542Sralph 	}
47518542Sralph 	p->wpid = 0;
47618542Sralph }
47718542Sralph 
47818542Sralph wstart(p)
47918542Sralph 	register struct tab *p;
48018542Sralph {
48122181Skarels 	register pid;
48222181Skarels 	time_t t;
48322181Skarels 	int dowait = 0;
48418542Sralph 
48522181Skarels 	time(&t);
48622181Skarels 	p->windcnt++;
48722181Skarels 	if ((t - p->windtime) >= 60) {
48822181Skarels 		p->windtime = t;
48922181Skarels 		p->windcnt = 1;
49022181Skarels 	} else if (p->windcnt >= 5) {
49122181Skarels 		dowait = 1;
49222181Skarels 		p->windtime = t;
49322181Skarels 		p->windcnt = 1;
49422181Skarels 	}
49522181Skarels 
49622181Skarels 	pid = fork();
49722181Skarels 
49822181Skarels 	if (pid == 0) {
49918542Sralph 		signal(SIGTERM, SIG_DFL);
50022181Skarels 		signal(SIGHUP,  SIG_IGN);
50122181Skarels 		sigsetmask(0);	/* since can be called from masked code */
50222181Skarels 		if (dowait) {
50322181Skarels 			syslog(LOG_ERR, "'%s %s' failing, sleeping", p->wcmd, p->line);
50422181Skarels 			closelog();
50522181Skarels 			sleep(30);
50622181Skarels 		}
507*42407Smarc 		if (setsid() < 0)
508*42407Smarc 			syslog(LOG_ERR, "setsid failed (window) %m");
50918542Sralph 		execit(p->wcmd, p->line);
51018542Sralph 		exit(0);
51118542Sralph 	}
51222181Skarels 	p->wpid = pid;
51318542Sralph }
51418542Sralph 
51522181Skarels #define NARGS	20	/* must be at least 4 */
51618542Sralph #define ARGLEN	512	/* total size for all the argument strings */
51718542Sralph 
51818542Sralph execit(s, arg)
51918542Sralph 	char *s;
52018542Sralph 	char *arg;	/* last argument on line */
52118542Sralph {
52218542Sralph 	char *argv[NARGS], args[ARGLEN], *envp[1];
52318542Sralph 	register char *sp = s;
52418542Sralph 	register char *ap = args;
52518542Sralph 	register char c;
52618542Sralph 	register int i;
52718542Sralph 
52818542Sralph 	/*
52918542Sralph 	 * First we have to set up the argument vector.
53018542Sralph 	 * "prog arg1 arg2" maps to exec("prog", "-", "arg1", "arg2").
53118542Sralph 	 */
53218542Sralph 	for (i = 1; i < NARGS - 2; i++) {
53318542Sralph 		argv[i] = ap;
53418542Sralph 		for (EVER) {
53518542Sralph 			if ((c = *sp++) == '\0' || ap >= &args[ARGLEN-1]) {
53618542Sralph 				*ap = '\0';
53718542Sralph 				goto done;
53818542Sralph 			}
53918542Sralph 			if (c == ' ') {
54018542Sralph 				*ap++ = '\0';
54118542Sralph 				while (*sp == ' ')
54218542Sralph 					sp++;
54318542Sralph 				if (*sp == '\0')
54418542Sralph 					goto done;
54518542Sralph 				break;
54618542Sralph 			}
54718542Sralph 			*ap++ = c;
54818542Sralph 		}
54918542Sralph 	}
55018542Sralph done:
55118542Sralph 	argv[0] = argv[1];
55218542Sralph 	argv[1] = "-";
55318542Sralph 	argv[i+1] = arg;
55418542Sralph 	argv[i+2] = 0;
55518542Sralph 	envp[0] = 0;
55618542Sralph 	execve(argv[0], &argv[1], envp);
55718542Sralph 	/* report failure of exec */
55818542Sralph 	syslog(LOG_ERR, "%s: %m", argv[0]);
55918542Sralph 	closelog();
56018542Sralph 	sleep(10);	/* prevent failures from eating machine */
56118542Sralph }
562