Annotation of src/usr.bin/tip/tipout.c, Revision 1.23
1.23 ! nicm 1: /* $OpenBSD: tipout.c,v 1.22 2010/06/29 21:34:50 nicm Exp $ */
1.4 millert 2: /* $NetBSD: tipout.c,v 1.5 1996/12/29 10:34:12 cgd Exp $ */
1.1 deraadt 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.
1.10 millert 16: * 3. Neither the name of the University nor the names of its contributors
1.1 deraadt 17: * may be used to endorse or promote products derived from this software
18: * without specific prior written permission.
19: *
20: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30: * SUCH DAMAGE.
31: */
32:
1.21 nicm 33: #include <sys/types.h>
34:
35: #include <poll.h>
36:
1.1 deraadt 37: #include "tip.h"
1.13 deraadt 38:
1.1 deraadt 39: /*
40: * tip
41: *
42: * lower fork of tip -- handles passive side
43: * reading from the remote host
44: */
45:
1.21 nicm 46: static void tipout_wait(void);
47: static void tipout_script(void);
48: static void tipout_write(char *, size_t);
49: static void tipout_sighandler(int);
1.1 deraadt 50:
1.21 nicm 51: volatile sig_atomic_t tipout_die;
1.14 moritz 52:
1.1 deraadt 53: /*
54: * TIPOUT wait state routine --
1.21 nicm 55: * sent by TIPIN when it wants to possess the remote host
1.1 deraadt 56: */
1.14 moritz 57: static void
1.21 nicm 58: tipout_wait(void)
1.1 deraadt 59: {
1.20 nicm 60: write(tipin_fd, &ccc, 1);
61: read(tipin_fd, &ccc, 1);
1.1 deraadt 62: }
63:
64: /*
65: * Scripting command interpreter --
66: * accepts script file name over the pipe and acts accordingly
67: */
1.14 moritz 68: static void
1.21 nicm 69: tipout_script(void)
1.1 deraadt 70: {
71: char c, line[256];
1.8 millert 72: char *pline = line;
1.1 deraadt 73: char reply;
74:
1.20 nicm 75: read(tipin_fd, &c, 1);
1.5 millert 76: while (c != '\n' && pline - line < sizeof(line)) {
1.1 deraadt 77: *pline++ = c;
1.20 nicm 78: read(tipin_fd, &c, 1);
1.1 deraadt 79: }
80: *pline = '\0';
1.23 ! nicm 81: if (vgetnum(SCRIPT) && fscript != NULL)
1.1 deraadt 82: fclose(fscript);
83: if (pline == line) {
1.23 ! nicm 84: vsetnum(SCRIPT, 0);
1.1 deraadt 85: reply = 'y';
86: } else {
87: if ((fscript = fopen(line, "a")) == NULL)
88: reply = 'n';
89: else {
90: reply = 'y';
1.23 ! nicm 91: vsetnum(SCRIPT, 1);
1.1 deraadt 92: }
93: }
1.20 nicm 94: write(tipin_fd, &reply, 1);
1.1 deraadt 95: }
96:
1.21 nicm 97: /*
98: * Write remote input out to stdout (and script file if enabled).
99: */
1.14 moritz 100: static void
1.21 nicm 101: tipout_write(char *buf, size_t len)
1.1 deraadt 102: {
1.21 nicm 103: char *cp;
104:
105: for (cp = buf; cp < buf + len; cp++)
106: *cp &= STRIP_PAR;
107:
108: write(STDOUT_FILENO, buf, len);
109:
1.23 ! nicm 110: if (vgetnum(SCRIPT) && fscript != NULL) {
! 111: if (!vgetnum(BEAUTIFY))
1.21 nicm 112: fwrite(buf, 1, len, fscript);
113: else {
114: for (cp = buf; cp < buf + len; cp++) {
115: if ((*cp >= ' ' && *cp <= '~') ||
1.23 ! nicm 116: any(*cp, vgetstr(EXCEPTIONS)))
! 117: putc(*cp, fscript);
1.21 nicm 118: }
119: }
120: }
1.1 deraadt 121: }
122:
1.21 nicm 123: /* ARGSUSED */
1.14 moritz 124: static void
1.21 nicm 125: tipout_sighandler(int signo)
1.1 deraadt 126: {
1.21 nicm 127: tipout_die = 1;
1.1 deraadt 128: }
129:
130: /*
131: * ****TIPOUT TIPOUT****
132: */
1.6 deraadt 133: void
1.13 deraadt 134: tipout(void)
1.1 deraadt 135: {
1.21 nicm 136: struct pollfd pfds[2];
137: char buf[BUFSIZ], ch;
138: ssize_t len;
139: int flag;
1.1 deraadt 140:
141: signal(SIGINT, SIG_IGN);
142: signal(SIGQUIT, SIG_IGN);
1.21 nicm 143:
144: tipout_die = 0;
145: signal(SIGTERM, tipout_sighandler);
146: signal(SIGHUP, tipout_sighandler);
147:
148: pfds[0].fd = tipin_fd;
149: pfds[0].events = POLLIN;
150:
151: pfds[1].fd = FD;
152: pfds[1].events = POLLIN;
153:
154: while (!tipout_die) {
155: if (poll(pfds, 2, INFTIM) == -1) {
156: if (errno == EINTR || errno == EAGAIN)
157: continue;
158: goto fail;
159: }
160:
161: if (pfds[0].revents & (POLLHUP|POLLERR))
162: goto fail;
163: if (pfds[0].revents & POLLIN) {
164: switch (read(tipin_fd, &ch, 1)) {
165: case 0:
166: goto fail;
167: case -1:
168: if (errno == EINTR || errno == EAGAIN)
169: break;
170: goto fail;
171: default:
172: switch (ch) {
173: case 'W': /* wait state */
174: tipout_wait();
175: break;
176: case 'S': /* script file */
177: tipout_script();
178: break;
179: case 'B': /* toggle beautify */
1.23 ! nicm 180: flag = !vgetnum(BEAUTIFY);
! 181: vsetnum(BEAUTIFY, flag);
1.21 nicm 182: break;
183: }
184: break;
1.1 deraadt 185: }
186: }
1.21 nicm 187:
188: if (pfds[1].revents & (POLLHUP|POLLERR))
189: goto fail;
190: if (pfds[1].revents & POLLIN) {
191: switch (len = read(FD, buf, BUFSIZ)) {
192: case 0:
193: goto fail;
194: case -1:
195: if (errno == EINTR || errno == EAGAIN)
196: continue;
197: goto fail;
198: default:
199: tipout_write(buf, len);
200: break;
1.1 deraadt 201: }
202: }
203: }
1.21 nicm 204:
205: fail:
1.23 ! nicm 206: if (vgetnum(SCRIPT) && fscript != NULL)
1.21 nicm 207: fclose(fscript);
208: kill(tipin_pid, SIGTERM);
209: exit(0);
1.1 deraadt 210: }