1*f20d1d23Sjoerg /* $NetBSD: tipout.c,v 1.15 2011/09/06 18:33:01 joerg Exp $ */
239801cccSjtc
361f28255Scgd /*
439801cccSjtc * Copyright (c) 1983, 1993
539801cccSjtc * The Regents of the University of California. All rights reserved.
661f28255Scgd *
761f28255Scgd * Redistribution and use in source and binary forms, with or without
861f28255Scgd * modification, are permitted provided that the following conditions
961f28255Scgd * are met:
1061f28255Scgd * 1. Redistributions of source code must retain the above copyright
1161f28255Scgd * notice, this list of conditions and the following disclaimer.
1261f28255Scgd * 2. Redistributions in binary form must reproduce the above copyright
1361f28255Scgd * notice, this list of conditions and the following disclaimer in the
1461f28255Scgd * documentation and/or other materials provided with the distribution.
1589aaa1bbSagc * 3. Neither the name of the University nor the names of its contributors
1661f28255Scgd * may be used to endorse or promote products derived from this software
1761f28255Scgd * without specific prior written permission.
1861f28255Scgd *
1961f28255Scgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2061f28255Scgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2161f28255Scgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2261f28255Scgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2361f28255Scgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2461f28255Scgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2561f28255Scgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2661f28255Scgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2761f28255Scgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2861f28255Scgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2961f28255Scgd * SUCH DAMAGE.
3061f28255Scgd */
3161f28255Scgd
32e37283e1Slukem #include <sys/cdefs.h>
33a973ebecStls #include <poll.h>
3461f28255Scgd #ifndef lint
3539801cccSjtc #if 0
3639801cccSjtc static char sccsid[] = "@(#)tipout.c 8.1 (Berkeley) 6/6/93";
3739801cccSjtc #endif
38*f20d1d23Sjoerg __RCSID("$NetBSD: tipout.c,v 1.15 2011/09/06 18:33:01 joerg Exp $");
3961f28255Scgd #endif /* not lint */
4061f28255Scgd
4161f28255Scgd #include "tip.h"
4261f28255Scgd /*
4361f28255Scgd * tip
4461f28255Scgd *
4561f28255Scgd * lower fork of tip -- handles passive side
4661f28255Scgd * reading from the remote host
4761f28255Scgd */
4861f28255Scgd
49a973ebecStls void intEMT(void);
50a973ebecStls void intIOT(void);
51a973ebecStls void intSYS(void);
52*f20d1d23Sjoerg __dead static void intTERM(int);
53e37283e1Slukem
5461f28255Scgd /*
5561f28255Scgd * TIPOUT wait state routine --
5661f28255Scgd * sent by TIPIN when it wants to posses the remote host
5761f28255Scgd */
5861f28255Scgd void
intIOT(void)59a973ebecStls intIOT(void)
6061f28255Scgd {
6161f28255Scgd
62ffe34450Schristos (void)write(repdes[1],&ccc,1); /* We got the message */
63ffe34450Schristos (void)read(fildes[0], &ccc,1); /* Now wait for coprocess */
6461f28255Scgd }
6561f28255Scgd
6661f28255Scgd /*
6761f28255Scgd * Scripting command interpreter --
6861f28255Scgd * accepts script file name over the pipe and acts accordingly
6961f28255Scgd */
7061f28255Scgd void
intEMT(void)71a973ebecStls intEMT(void)
7261f28255Scgd {
7361f28255Scgd char c, line[256];
74e37283e1Slukem char *pline = line;
7561f28255Scgd char reply;
7661f28255Scgd
77ffe34450Schristos (void)read(fildes[0], &c, 1); /* We got the message */
78923d7551Smrg while (c != '\n' && line + sizeof line - pline > 0) {
7961f28255Scgd *pline++ = c;
80ffe34450Schristos (void)read(fildes[0], &c, 1);
8161f28255Scgd }
8261f28255Scgd *pline = '\0';
8361f28255Scgd if (boolean(value(SCRIPT)) && fscript != NULL)
84ffe34450Schristos (void)fclose(fscript);
8561f28255Scgd if (pline == line) {
8688caf985Scgd setboolean(value(SCRIPT), FALSE);
8761f28255Scgd reply = 'y';
8861f28255Scgd } else {
8961f28255Scgd if ((fscript = fopen(line, "a")) == NULL)
9061f28255Scgd reply = 'n';
9161f28255Scgd else {
9261f28255Scgd reply = 'y';
9388caf985Scgd setboolean(value(SCRIPT), TRUE);
9461f28255Scgd }
9561f28255Scgd }
96ffe34450Schristos (void)write(repdes[1], &reply, 1); /* Now coprocess waits for us */
9761f28255Scgd }
9861f28255Scgd
99*f20d1d23Sjoerg static void
100c4341bc3Schristos /*ARGSUSED*/
intTERM(int dummy __unused)101ffe34450Schristos intTERM(int dummy __unused)
10261f28255Scgd {
10361f28255Scgd
10461f28255Scgd if (boolean(value(SCRIPT)) && fscript != NULL)
105ffe34450Schristos (void)fclose(fscript);
10661f28255Scgd exit(0);
10761f28255Scgd }
10861f28255Scgd
10961f28255Scgd void
intSYS(void)110a973ebecStls intSYS(void)
11161f28255Scgd {
11261f28255Scgd
11388caf985Scgd setboolean(value(BEAUTIFY), !boolean(value(BEAUTIFY)));
11461f28255Scgd }
11561f28255Scgd
11661f28255Scgd /*
11761f28255Scgd * ****TIPOUT TIPOUT****
11861f28255Scgd */
119e37283e1Slukem void
tipout(void)12058c2151fSperry tipout(void)
12161f28255Scgd {
12261f28255Scgd char buf[BUFSIZ];
123e37283e1Slukem char *cp;
124e37283e1Slukem int cnt;
12561f28255Scgd int omask;
126a973ebecStls struct pollfd pfd[2];
12761f28255Scgd
128ffe34450Schristos (void)signal(SIGINT, SIG_IGN);
129ffe34450Schristos (void)signal(SIGQUIT, SIG_IGN);
130ffe34450Schristos (void)signal(SIGHUP, intTERM); /* for dial-ups */
131ffe34450Schristos (void)signal(SIGTERM, intTERM); /* time to go signal*/
132a973ebecStls
133a973ebecStls pfd[0].fd = attndes[0];
134a973ebecStls pfd[0].events = POLLIN;
135a973ebecStls pfd[1].fd = FD;
136a973ebecStls pfd[1].events = POLLIN|POLLHUP;
137a973ebecStls
138ffe34450Schristos for (omask = 0;; (void)sigsetmask(omask)) {
139a973ebecStls
140a973ebecStls if (poll(pfd, 2, -1) > 0) {
141a973ebecStls
142a973ebecStls if (pfd[0].revents & POLLIN)
143a973ebecStls if (read(attndes[0], &ccc, 1) > 0) {
144a973ebecStls switch(ccc) {
145a973ebecStls case 'W':
146a973ebecStls intIOT(); /* TIPIN wants us to wait */
147a973ebecStls break;
148a973ebecStls case 'S':
149a973ebecStls intEMT(); /* TIPIN wants us to script */
150a973ebecStls break;
151a973ebecStls case 'B':
152a973ebecStls intSYS(); /* "Beautify" value toggle */
153a973ebecStls break;
154a973ebecStls default:
155a973ebecStls break;
156a973ebecStls }
157a973ebecStls }
158a973ebecStls }
159a973ebecStls
160a973ebecStls if (pfd[1].revents & (POLLIN|POLLHUP)) {
16161f28255Scgd cnt = read(FD, buf, BUFSIZ);
16261f28255Scgd if (cnt <= 0) {
163f1f29c8bSgavan /* lost carrier || EOF */
164f1f29c8bSgavan if ((cnt < 0 && errno == EIO) || (cnt == 0)) {
165ffe34450Schristos (void)sigblock(sigmask(SIGTERM));
166e37283e1Slukem intTERM(0);
16761f28255Scgd /*NOTREACHED*/
16861f28255Scgd }
16961f28255Scgd continue;
17061f28255Scgd }
171a973ebecStls omask = sigblock(SIGTERM);
17261f28255Scgd for (cp = buf; cp < buf + cnt; cp++)
173258108ceSpk *cp &= STRIP_PAR;
174ffe34450Schristos (void)write(1, buf, (size_t)cnt);
17561f28255Scgd if (boolean(value(SCRIPT)) && fscript != NULL) {
17661f28255Scgd if (!boolean(value(BEAUTIFY))) {
177ffe34450Schristos (void)fwrite(buf, 1, (size_t)cnt, fscript);
17861f28255Scgd continue;
17961f28255Scgd }
18061f28255Scgd for (cp = buf; cp < buf + cnt; cp++)
18161f28255Scgd if ((*cp >= ' ' && *cp <= '~') ||
18261f28255Scgd any(*cp, value(EXCEPTIONS)))
183ffe34450Schristos (void)putc(*cp, fscript);
18461f28255Scgd }
18561f28255Scgd }
18661f28255Scgd }
187a973ebecStls }
188