tipout.c revision 88276
188276Smarkm/*	$OpenBSD: tipout.c,v 1.8 2001/10/24 18:38:58 millert Exp $	*/
288276Smarkm/*	$NetBSD: tipout.c,v 1.5 1996/12/29 10:34:12 cgd Exp $	*/
388276Smarkm
47527Sjkh/*
57527Sjkh * Copyright (c) 1983, 1993
67527Sjkh *	The Regents of the University of California.  All rights reserved.
77527Sjkh *
87527Sjkh * Redistribution and use in source and binary forms, with or without
97527Sjkh * modification, are permitted provided that the following conditions
107527Sjkh * are met:
117527Sjkh * 1. Redistributions of source code must retain the above copyright
127527Sjkh *    notice, this list of conditions and the following disclaimer.
137527Sjkh * 2. Redistributions in binary form must reproduce the above copyright
147527Sjkh *    notice, this list of conditions and the following disclaimer in the
157527Sjkh *    documentation and/or other materials provided with the distribution.
167527Sjkh * 3. All advertising materials mentioning features or use of this software
177527Sjkh *    must display the following acknowledgement:
187527Sjkh *	This product includes software developed by the University of
197527Sjkh *	California, Berkeley and its contributors.
207527Sjkh * 4. Neither the name of the University nor the names of its contributors
217527Sjkh *    may be used to endorse or promote products derived from this software
227527Sjkh *    without specific prior written permission.
237527Sjkh *
247527Sjkh * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
257527Sjkh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
267527Sjkh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
277527Sjkh * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
287527Sjkh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
297527Sjkh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
307527Sjkh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
317527Sjkh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
327527Sjkh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
337527Sjkh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
347527Sjkh * SUCH DAMAGE.
357527Sjkh */
367527Sjkh
3788276Smarkm#include <sys/cdefs.h>
3888276Smarkm__FBSDID("$FreeBSD: head/usr.bin/tip/tip/tipout.c 88276 2001-12-20 14:25:46Z markm $");
3988276Smarkm
407527Sjkh#ifndef lint
4128365Scharnier#if 0
427527Sjkhstatic char sccsid[] = "@(#)tipout.c	8.1 (Berkeley) 6/6/93";
4388276Smarkmstatic char rcsid[] = "$OpenBSD: tipout.c,v 1.8 2001/10/24 18:38:58 millert Exp $";
4428365Scharnier#endif
457527Sjkh#endif /* not lint */
467527Sjkh
477527Sjkh#include "tip.h"
487527Sjkh/*
497527Sjkh * tip
507527Sjkh *
517527Sjkh * lower fork of tip -- handles passive side
527527Sjkh *  reading from the remote host
537527Sjkh */
547527Sjkh
557527Sjkhstatic	jmp_buf sigbuf;
567527Sjkh
577527Sjkh/*
587527Sjkh * TIPOUT wait state routine --
597527Sjkh *   sent by TIPIN when it wants to posses the remote host
607527Sjkh */
617527Sjkhvoid
627527SjkhintIOT()
637527Sjkh{
647527Sjkh
657527Sjkh	write(repdes[1],&ccc,1);
667527Sjkh	read(fildes[0], &ccc,1);
677527Sjkh	longjmp(sigbuf, 1);
687527Sjkh}
697527Sjkh
707527Sjkh/*
717527Sjkh * Scripting command interpreter --
727527Sjkh *  accepts script file name over the pipe and acts accordingly
737527Sjkh */
747527Sjkhvoid
757527SjkhintEMT()
767527Sjkh{
777527Sjkh	char c, line[256];
7888276Smarkm	char *pline = line;
797527Sjkh	char reply;
807527Sjkh
817527Sjkh	read(fildes[0], &c, 1);
8228686Simp	while (c != '\n' && pline - line < sizeof(line)) {
837527Sjkh		*pline++ = c;
847527Sjkh		read(fildes[0], &c, 1);
857527Sjkh	}
867527Sjkh	*pline = '\0';
877527Sjkh	if (boolean(value(SCRIPT)) && fscript != NULL)
887527Sjkh		fclose(fscript);
897527Sjkh	if (pline == line) {
9088276Smarkm		setboolean(value(SCRIPT), FALSE);
917527Sjkh		reply = 'y';
927527Sjkh	} else {
937527Sjkh		if ((fscript = fopen(line, "a")) == NULL)
947527Sjkh			reply = 'n';
957527Sjkh		else {
967527Sjkh			reply = 'y';
9788276Smarkm			setboolean(value(SCRIPT), TRUE);
987527Sjkh		}
997527Sjkh	}
1007527Sjkh	write(repdes[1], &reply, 1);
1017527Sjkh	longjmp(sigbuf, 1);
1027527Sjkh}
1037527Sjkh
1047527Sjkhvoid
1057527SjkhintTERM()
1067527Sjkh{
1077527Sjkh
1087527Sjkh	if (boolean(value(SCRIPT)) && fscript != NULL)
1097527Sjkh		fclose(fscript);
1107527Sjkh	exit(0);
1117527Sjkh}
1127527Sjkh
1137527Sjkhvoid
1147527SjkhintSYS()
1157527Sjkh{
1167527Sjkh
11788276Smarkm	setboolean(value(BEAUTIFY), !boolean(value(BEAUTIFY)));
1187527Sjkh	longjmp(sigbuf, 1);
1197527Sjkh}
1207527Sjkh
1217527Sjkh/*
1227527Sjkh * ****TIPOUT   TIPOUT****
1237527Sjkh */
12428365Scharniervoid
1257527Sjkhtipout()
1267527Sjkh{
1277527Sjkh	char buf[BUFSIZ];
12888276Smarkm	char *cp;
12988276Smarkm	int cnt;
13088276Smarkm	sigset_t mask, omask;
1317527Sjkh
1327527Sjkh	signal(SIGINT, SIG_IGN);
1337527Sjkh	signal(SIGQUIT, SIG_IGN);
1347527Sjkh	signal(SIGEMT, intEMT);		/* attention from TIPIN */
1357527Sjkh	signal(SIGTERM, intTERM);	/* time to go signal */
1367527Sjkh	signal(SIGIOT, intIOT);		/* scripting going on signal */
1377527Sjkh	signal(SIGHUP, intTERM);	/* for dial-ups */
1387527Sjkh	signal(SIGSYS, intSYS);		/* beautify toggle */
1397527Sjkh	(void) setjmp(sigbuf);
14088276Smarkm	sigprocmask(SIG_BLOCK, NULL, &omask);
14188276Smarkm	for (;;) {
14288276Smarkm		sigprocmask(SIG_SETMASK, &omask, NULL);
1437527Sjkh		cnt = read(FD, buf, BUFSIZ);
1447527Sjkh		if (cnt <= 0) {
1457527Sjkh			/* lost carrier */
1467527Sjkh			if (cnt < 0 && errno == EIO) {
14788276Smarkm				sigemptyset(&mask);
14888276Smarkm				sigaddset(&mask, SIGTERM);
14988276Smarkm				sigprocmask(SIG_BLOCK, &mask, NULL);
1507527Sjkh				intTERM();
1517527Sjkh				/*NOTREACHED*/
1527527Sjkh			}
1537527Sjkh			continue;
1547527Sjkh		}
15588276Smarkm		sigemptyset(&mask);
15688276Smarkm		sigaddset(&mask, SIGEMT);
15788276Smarkm		sigaddset(&mask, SIGTERM);
15888276Smarkm		sigaddset(&mask, SIGIOT);
15988276Smarkm		sigaddset(&mask, SIGSYS);
16088276Smarkm		sigprocmask(SIG_BLOCK, &mask, NULL);
1617527Sjkh		for (cp = buf; cp < buf + cnt; cp++)
16288276Smarkm			*cp &= STRIP_PAR;
16388276Smarkm		write(1, buf, cnt);
1647527Sjkh		if (boolean(value(SCRIPT)) && fscript != NULL) {
1657527Sjkh			if (!boolean(value(BEAUTIFY))) {
1667527Sjkh				fwrite(buf, 1, cnt, fscript);
1677527Sjkh				continue;
1687527Sjkh			}
1697527Sjkh			for (cp = buf; cp < buf + cnt; cp++)
1707527Sjkh				if ((*cp >= ' ' && *cp <= '~') ||
1717527Sjkh				    any(*cp, value(EXCEPTIONS)))
1727527Sjkh					putc(*cp, fscript);
1737527Sjkh		}
1747527Sjkh	}
1757527Sjkh}
176