1161754Sru/* $OpenBSD: tipout.c,v 1.18 2006/05/31 07:03:08 jason Exp $ */ 288276Smarkm/* $NetBSD: tipout.c,v 1.5 1996/12/29 10:34:12 cgd Exp $ */ 388276Smarkm 4331722Seadler/* 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. 16161754Sru * 3. Neither the name of the University nor the names of its contributors 177527Sjkh * may be used to endorse or promote products derived from this software 187527Sjkh * without specific prior written permission. 197527Sjkh * 207527Sjkh * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 217527Sjkh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 227527Sjkh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 237527Sjkh * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 247527Sjkh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 257527Sjkh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 267527Sjkh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 277527Sjkh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 287527Sjkh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 297527Sjkh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 307527Sjkh * SUCH DAMAGE. 317527Sjkh */ 327527Sjkh 3388276Smarkm#include <sys/cdefs.h> 3488276Smarkm__FBSDID("$FreeBSD$"); 3588276Smarkm 367527Sjkh#ifndef lint 3728365Scharnier#if 0 387527Sjkhstatic char sccsid[] = "@(#)tipout.c 8.1 (Berkeley) 6/6/93"; 39161754Srustatic const char rcsid[] = "$OpenBSD: tipout.c,v 1.18 2006/05/31 07:03:08 jason Exp $"; 4028365Scharnier#endif 417527Sjkh#endif /* not lint */ 427527Sjkh 437527Sjkh#include "tip.h" 44161754Sru 457527Sjkh/* 467527Sjkh * tip 477527Sjkh * 487527Sjkh * lower fork of tip -- handles passive side 497527Sjkh * reading from the remote host 507527Sjkh */ 517527Sjkh 527527Sjkhstatic jmp_buf sigbuf; 537527Sjkh 54161754Srustatic void intIOT(int); 55161754Srustatic void intEMT(int); 56161754Srustatic void intTERM(int); 57161754Srustatic void intSYS(int); 58161754Sru 597527Sjkh/* 607527Sjkh * TIPOUT wait state routine -- 617527Sjkh * sent by TIPIN when it wants to posses the remote host 627527Sjkh */ 63161754Sru/*ARGSUSED*/ 64161754Srustatic void 65161754SruintIOT(int signo) 667527Sjkh{ 677527Sjkh write(repdes[1],&ccc,1); 687527Sjkh read(fildes[0], &ccc,1); 697527Sjkh longjmp(sigbuf, 1); 707527Sjkh} 717527Sjkh 727527Sjkh/* 737527Sjkh * Scripting command interpreter -- 747527Sjkh * accepts script file name over the pipe and acts accordingly 757527Sjkh */ 76161754Sru/*ARGSUSED*/ 77161754Srustatic void 78161754SruintEMT(int signo) 797527Sjkh{ 807527Sjkh char c, line[256]; 8188276Smarkm char *pline = line; 827527Sjkh char reply; 837527Sjkh 847527Sjkh read(fildes[0], &c, 1); 85161781Sru while (c != '\n' && (size_t)(pline - line) < sizeof(line)) { 867527Sjkh *pline++ = c; 877527Sjkh read(fildes[0], &c, 1); 887527Sjkh } 897527Sjkh *pline = '\0'; 907527Sjkh if (boolean(value(SCRIPT)) && fscript != NULL) 917527Sjkh fclose(fscript); 927527Sjkh if (pline == line) { 9388276Smarkm setboolean(value(SCRIPT), FALSE); 947527Sjkh reply = 'y'; 957527Sjkh } else { 967527Sjkh if ((fscript = fopen(line, "a")) == NULL) 977527Sjkh reply = 'n'; 987527Sjkh else { 997527Sjkh reply = 'y'; 10088276Smarkm setboolean(value(SCRIPT), TRUE); 1017527Sjkh } 1027527Sjkh } 1037527Sjkh write(repdes[1], &reply, 1); 1047527Sjkh longjmp(sigbuf, 1); 1057527Sjkh} 1067527Sjkh 107161754Srustatic void 108161754SruintTERM(int signo) 1097527Sjkh{ 1107527Sjkh if (boolean(value(SCRIPT)) && fscript != NULL) 1117527Sjkh fclose(fscript); 112161754Sru if (signo && tipin_pid) 113161754Sru kill(tipin_pid, signo); 1147527Sjkh exit(0); 1157527Sjkh} 1167527Sjkh 117161754Sru/*ARGSUSED*/ 118161754Srustatic void 119161754SruintSYS(int signo) 1207527Sjkh{ 12188276Smarkm setboolean(value(BEAUTIFY), !boolean(value(BEAUTIFY))); 1227527Sjkh longjmp(sigbuf, 1); 1237527Sjkh} 1247527Sjkh 1257527Sjkh/* 1267527Sjkh * ****TIPOUT TIPOUT**** 1277527Sjkh */ 12828365Scharniervoid 129161754Srutipout(void) 1307527Sjkh{ 1317527Sjkh char buf[BUFSIZ]; 13288276Smarkm char *cp; 133161754Sru ssize_t scnt; 134161754Sru size_t cnt; 13588276Smarkm sigset_t mask, omask; 1367527Sjkh 1377527Sjkh signal(SIGINT, SIG_IGN); 1387527Sjkh signal(SIGQUIT, SIG_IGN); 1397527Sjkh signal(SIGEMT, intEMT); /* attention from TIPIN */ 1407527Sjkh signal(SIGTERM, intTERM); /* time to go signal */ 1417527Sjkh signal(SIGIOT, intIOT); /* scripting going on signal */ 1427527Sjkh signal(SIGHUP, intTERM); /* for dial-ups */ 1437527Sjkh signal(SIGSYS, intSYS); /* beautify toggle */ 1447527Sjkh (void) setjmp(sigbuf); 14588276Smarkm sigprocmask(SIG_BLOCK, NULL, &omask); 14688276Smarkm for (;;) { 14788276Smarkm sigprocmask(SIG_SETMASK, &omask, NULL); 148161754Sru scnt = read(FD, buf, BUFSIZ); 149161754Sru if (scnt <= 0) { 1507527Sjkh /* lost carrier */ 151230654Sphk if (scnt == 0 || 152230654Sphk (scnt < 0 && (errno == EIO || errno == ENXIO))) { 15388276Smarkm sigemptyset(&mask); 15488276Smarkm sigaddset(&mask, SIGTERM); 15588276Smarkm sigprocmask(SIG_BLOCK, &mask, NULL); 156230654Sphk intTERM(SIGHUP); 1577527Sjkh /*NOTREACHED*/ 1587527Sjkh } 1597527Sjkh continue; 1607527Sjkh } 161161754Sru cnt = scnt; 16288276Smarkm sigemptyset(&mask); 16388276Smarkm sigaddset(&mask, SIGEMT); 16488276Smarkm sigaddset(&mask, SIGTERM); 16588276Smarkm sigaddset(&mask, SIGIOT); 16688276Smarkm sigaddset(&mask, SIGSYS); 16788276Smarkm sigprocmask(SIG_BLOCK, &mask, NULL); 1687527Sjkh for (cp = buf; cp < buf + cnt; cp++) 16988276Smarkm *cp &= STRIP_PAR; 170161754Sru write(STDOUT_FILENO, buf, cnt); 1717527Sjkh if (boolean(value(SCRIPT)) && fscript != NULL) { 1727527Sjkh if (!boolean(value(BEAUTIFY))) { 1737527Sjkh fwrite(buf, 1, cnt, fscript); 174221727Sphk } else { 175221727Sphk for (cp = buf; cp < buf + cnt; cp++) 176221727Sphk if ((*cp >= ' ' && *cp <= '~') || 177221727Sphk any(*cp, value(EXCEPTIONS))) 178221727Sphk putc(*cp, fscript); 1797527Sjkh } 180221727Sphk for (cp = buf; cp < buf + cnt; cp++) { 181221727Sphk if (!isgraph(*cp)) { 182221727Sphk fflush(fscript); 183221727Sphk break; 184221727Sphk } 185221727Sphk } 1867527Sjkh } 1877527Sjkh } 1887527Sjkh} 189