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