xref: /illumos-gate/usr/src/cmd/tip/tipout.c (revision 94e1761e)
1 /*
2  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*
7  * Copyright (c) 1983 Regents of the University of California.
8  * All rights reserved.  The Berkeley software License Agreement
9  * specifies the terms and conditions for redistribution.
10  */
11 
12 #pragma ident	"%Z%%M%	%I%	%E% SMI"
13 
14 #include "tip.h"
15 #include <limits.h>
16 
17 /*
18  * tip
19  *
20  * lower fork of tip -- handles passive side
21  *  reading from the remote host
22  */
23 
24 static	sigjmp_buf sigbuf;
25 
26 /*
27  * TIPOUT wait state routine --
28  *   sent by TIPIN when it wants to posses the remote host
29  */
30 void
31 intIOT(void)
32 {
33 
34 	(void) write(repdes[1], &ccc, 1);
35 	(void) read(fildes[0], &ccc, 1);
36 	siglongjmp(sigbuf, 1);
37 }
38 
39 /*
40  * Scripting command interpreter --
41  *  accepts script file name over the pipe and acts accordingly
42  */
43 void
44 intEMT(void)
45 {
46 	char c, line[PATH_MAX];
47 	char *pline = line;
48 	char reply;
49 
50 	(void) read(fildes[0], &c, 1);
51 	while (c != '\n' && line + sizeof (line) - pline > 1) {
52 		*pline++ = c;
53 		(void) read(fildes[0], &c, 1);
54 	}
55 	*pline = '\0';
56 	if (boolean(value(SCRIPT)) && fscript != NULL)
57 		(void) fclose(fscript);
58 	if (pline == line) {
59 		boolean(value(SCRIPT)) = FALSE;
60 		reply = 'y';
61 	} else {
62 		if ((fscript = fopen(line, "a")) == NULL)
63 			reply = 'n';
64 		else {
65 			reply = 'y';
66 			boolean(value(SCRIPT)) = TRUE;
67 		}
68 	}
69 	(void) write(repdes[1], &reply, 1);
70 	siglongjmp(sigbuf, 1);
71 }
72 
73 void
74 intTERM(void)
75 {
76 
77 	if (boolean(value(SCRIPT)) && fscript != NULL)
78 		(void) fclose(fscript);
79 	exit(0);
80 }
81 
82 void
83 intSYS(void)
84 {
85 
86 	boolean(value(BEAUTIFY)) = !boolean(value(BEAUTIFY));
87 	siglongjmp(sigbuf, 1);
88 }
89 
90 /*
91  * ****TIPOUT   TIPOUT****
92  */
93 void
94 tipout(void)
95 {
96 	char buf[BUFSIZ];
97 	char *cp;
98 	int cnt;
99 	sigset_t omask, bmask, tmask;
100 
101 	(void) signal(SIGINT, SIG_IGN);
102 	(void) signal(SIGQUIT, SIG_IGN);
103 	/* attention from TIPIN */
104 	(void) signal(SIGEMT, (sig_handler_t)intEMT);
105 	/* time to go signal */
106 	(void) signal(SIGTERM, (sig_handler_t)intTERM);
107 	/* scripting going on signal */
108 	(void) signal(SIGIOT, (sig_handler_t)intIOT);
109 	/* for dial-ups */
110 	(void) signal(SIGHUP, (sig_handler_t)intTERM);
111 	/* beautify toggle */
112 	(void) signal(SIGSYS, (sig_handler_t)intSYS);
113 	(void) sigsetjmp(sigbuf, 1);
114 
115 	(void) sigemptyset(&omask);
116 	(void) sigemptyset(&bmask);
117 	(void) sigaddset(&bmask, SIGEMT);
118 	(void) sigaddset(&bmask, SIGTERM);
119 	(void) sigaddset(&bmask, SIGIOT);
120 	(void) sigaddset(&bmask, SIGSYS);
121 	(void) sigemptyset(&tmask);
122 	(void) sigaddset(&tmask, SIGTERM);
123 	for (;;) {
124 		cnt = read(FD, buf, BUFSIZ);
125 		if (cnt <= 0) {
126 			/*
127 			 * If dialback is specified, ignore the hangup
128 			 * and clear the hangup condition on the device.
129 			 */
130 			if (cnt == 0 && DB) {
131 				int fd;
132 
133 				DB = 0;
134 				if ((fd = open(DV, O_RDWR)) >= 0) {
135 					if (fd != FD)
136 						(void) close(fd);
137 				}
138 				continue;
139 			}
140 			/* lost carrier */
141 			if ((cnt < 0 && errno == EIO) ||
142 			    (cnt == 0)) {
143 				(void) sigprocmask(SIG_BLOCK, &tmask, NULL);
144 				intTERM();
145 				/*NOTREACHED*/
146 			}
147 		} else {
148 			(void) sigprocmask(SIG_BLOCK, &bmask, &omask);
149 			if (!noparity)
150 				for (cp = buf; cp < buf + cnt; cp++)
151 					*cp &= 0177;
152 
153 			(void) write(1, buf, cnt);
154 			if (boolean(value(SCRIPT)) && fscript != NULL) {
155 				if (!boolean(value(BEAUTIFY))) {
156 					(void) fwrite(buf, 1, cnt, fscript);
157 				} else {
158 					for (cp = buf; cp < buf + cnt; cp++)
159 						if ((*cp >= ' ' && *cp <= '~')||
160 						    any(*cp, value(EXCEPTIONS)))
161 							(void) putc(*cp,
162 							    fscript);
163 				}
164 			}
165 		}
166 		(void) sigprocmask(SIG_SETMASK, &omask, NULL);
167 	}
168 }
169