tipout.c revision 88276
1/*	$OpenBSD: tipout.c,v 1.8 2001/10/24 18:38:58 millert Exp $	*/
2/*	$NetBSD: tipout.c,v 1.5 1996/12/29 10:34:12 cgd Exp $	*/
3
4/*
5 * Copyright (c) 1983, 1993
6 *	The Regents of the University of California.  All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 *    must display the following acknowledgement:
18 *	This product includes software developed by the University of
19 *	California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 *    may be used to endorse or promote products derived from this software
22 *    without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#include <sys/cdefs.h>
38__FBSDID("$FreeBSD: head/usr.bin/tip/tip/tipout.c 88276 2001-12-20 14:25:46Z markm $");
39
40#ifndef lint
41#if 0
42static char sccsid[] = "@(#)tipout.c	8.1 (Berkeley) 6/6/93";
43static char rcsid[] = "$OpenBSD: tipout.c,v 1.8 2001/10/24 18:38:58 millert Exp $";
44#endif
45#endif /* not lint */
46
47#include "tip.h"
48/*
49 * tip
50 *
51 * lower fork of tip -- handles passive side
52 *  reading from the remote host
53 */
54
55static	jmp_buf sigbuf;
56
57/*
58 * TIPOUT wait state routine --
59 *   sent by TIPIN when it wants to posses the remote host
60 */
61void
62intIOT()
63{
64
65	write(repdes[1],&ccc,1);
66	read(fildes[0], &ccc,1);
67	longjmp(sigbuf, 1);
68}
69
70/*
71 * Scripting command interpreter --
72 *  accepts script file name over the pipe and acts accordingly
73 */
74void
75intEMT()
76{
77	char c, line[256];
78	char *pline = line;
79	char reply;
80
81	read(fildes[0], &c, 1);
82	while (c != '\n' && pline - line < sizeof(line)) {
83		*pline++ = c;
84		read(fildes[0], &c, 1);
85	}
86	*pline = '\0';
87	if (boolean(value(SCRIPT)) && fscript != NULL)
88		fclose(fscript);
89	if (pline == line) {
90		setboolean(value(SCRIPT), FALSE);
91		reply = 'y';
92	} else {
93		if ((fscript = fopen(line, "a")) == NULL)
94			reply = 'n';
95		else {
96			reply = 'y';
97			setboolean(value(SCRIPT), TRUE);
98		}
99	}
100	write(repdes[1], &reply, 1);
101	longjmp(sigbuf, 1);
102}
103
104void
105intTERM()
106{
107
108	if (boolean(value(SCRIPT)) && fscript != NULL)
109		fclose(fscript);
110	exit(0);
111}
112
113void
114intSYS()
115{
116
117	setboolean(value(BEAUTIFY), !boolean(value(BEAUTIFY)));
118	longjmp(sigbuf, 1);
119}
120
121/*
122 * ****TIPOUT   TIPOUT****
123 */
124void
125tipout()
126{
127	char buf[BUFSIZ];
128	char *cp;
129	int cnt;
130	sigset_t mask, omask;
131
132	signal(SIGINT, SIG_IGN);
133	signal(SIGQUIT, SIG_IGN);
134	signal(SIGEMT, intEMT);		/* attention from TIPIN */
135	signal(SIGTERM, intTERM);	/* time to go signal */
136	signal(SIGIOT, intIOT);		/* scripting going on signal */
137	signal(SIGHUP, intTERM);	/* for dial-ups */
138	signal(SIGSYS, intSYS);		/* beautify toggle */
139	(void) setjmp(sigbuf);
140	sigprocmask(SIG_BLOCK, NULL, &omask);
141	for (;;) {
142		sigprocmask(SIG_SETMASK, &omask, NULL);
143		cnt = read(FD, buf, BUFSIZ);
144		if (cnt <= 0) {
145			/* lost carrier */
146			if (cnt < 0 && errno == EIO) {
147				sigemptyset(&mask);
148				sigaddset(&mask, SIGTERM);
149				sigprocmask(SIG_BLOCK, &mask, NULL);
150				intTERM();
151				/*NOTREACHED*/
152			}
153			continue;
154		}
155		sigemptyset(&mask);
156		sigaddset(&mask, SIGEMT);
157		sigaddset(&mask, SIGTERM);
158		sigaddset(&mask, SIGIOT);
159		sigaddset(&mask, SIGSYS);
160		sigprocmask(SIG_BLOCK, &mask, NULL);
161		for (cp = buf; cp < buf + cnt; cp++)
162			*cp &= STRIP_PAR;
163		write(1, buf, cnt);
164		if (boolean(value(SCRIPT)) && fscript != NULL) {
165			if (!boolean(value(BEAUTIFY))) {
166				fwrite(buf, 1, cnt, fscript);
167				continue;
168			}
169			for (cp = buf; cp < buf + cnt; cp++)
170				if ((*cp >= ' ' && *cp <= '~') ||
171				    any(*cp, value(EXCEPTIONS)))
172					putc(*cp, fscript);
173		}
174	}
175}
176