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