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
intIOT(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
intEMT(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
intTERM(void)74 intTERM(void)
75 {
76
77 if (boolean(value(SCRIPT)) && fscript != NULL)
78 (void) fclose(fscript);
79 exit(0);
80 }
81
82 void
intSYS(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
tipout(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