1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29
30 /*
31 * This is a new line.c, which consists of line.c and culine.c
32 * merged together.
33 */
34
35 #include "mt.h"
36 #include "uucp.h"
37
38 static const struct sg_spds {
39 int sp_val,
40 sp_name;
41 } spds[] = {
42 { 50, B50},
43 { 75, B75},
44 { 110, B110},
45 { 134, B134},
46 { 150, B150},
47 { 200, B200},
48 { 300, B300},
49 { 600, B600},
50 {1200, B1200},
51 {1800, B1800},
52 {2400, B2400},
53 {4800, B4800},
54 {9600, B9600},
55 #ifdef EXTA
56 {19200, EXTA},
57 #endif
58 #ifdef B19200
59 {19200, B19200},
60 #endif
61 #ifdef B38400
62 {38400, B38400},
63 #endif
64 {57600, B57600},
65 {76800, B76800},
66 {115200, B115200},
67 {153600, B153600},
68 {230400, B230400},
69 {307200, B307200},
70 {460800, B460800},
71 {921600, B921600},
72 {0, 0}
73 };
74
75 #define PACKSIZE 64
76 #define HEADERSIZE 6
77
78 #define SNDFILE 'S'
79 #define RCVFILE 'R'
80 #define RESET 'X'
81
82 static int Saved_line; /* was savline() successful? */
83 static int Saved_termios; /* was termios saved? */
84 static int
85 Oddflag, /* Default is no parity */
86 Evenflag, /* Default is no parity */
87 Duplex = 1, /* Default is full duplex */
88 Terminal, /* Default is no terminal */
89 line_8bit = -1; /* Default is same as terminal */
90
91 static const char P_PARITY[] = "Parity option error\r\n";
92
93 static struct termio Savettyb;
94 static struct termios Savettybs;
95 /*
96 * set speed/echo/mode...
97 * tty -> terminal name
98 * spwant -> speed
99 * type -> type
100 *
101 * if spwant == 0, speed is untouched
102 * type is unused, but needed for compatibility
103 *
104 * return:
105 * none
106 */
107 /*ARGSUSED*/
108 static void
fixline(int tty,int spwant,int type)109 fixline(int tty, int spwant, int type)
110 {
111 register const struct sg_spds *ps;
112 struct termio ttbuf;
113 struct termios ttbufs;
114 int speed = -1;
115 int i, istermios, ospeed;
116
117 DEBUG(6, "fixline(%d, ", tty);
118 DEBUG(6, "%d)\n", spwant);
119 if ((istermios = (*Ioctl)(tty, TCGETS, &ttbufs)) < 0) {
120 if ((*Ioctl)(tty, TCGETA, &ttbuf) != 0)
121 return;
122 ttbufs.c_lflag = ttbuf.c_lflag;
123 ttbufs.c_oflag = ttbuf.c_oflag;
124 ttbufs.c_iflag = ttbuf.c_iflag;
125 ttbufs.c_cflag = ttbuf.c_cflag;
126 for (i = 0; i < NCC; i++)
127 ttbufs.c_cc[i] = ttbuf.c_cc[i];
128 }
129 if (spwant > 0) {
130 for (ps = spds; ps->sp_val; ps++)
131 if (ps->sp_val == spwant) {
132 speed = ps->sp_name;
133 break;
134 }
135 if (speed < 0) {
136 /*EMPTY*/
137 DEBUG(5, "speed (%d) not supported\n", spwant);
138 }
139 ASSERT(speed >= 0, "BAD SPEED", "", spwant);
140 ttbufs.c_cflag &= 0xffff0000;
141 (void) cfsetospeed(&ttbufs, speed);
142 } else { /* determine the current speed setting */
143 ospeed = cfgetospeed(&ttbufs);
144 ttbufs.c_cflag &= 0xffff0000;
145 (void) cfsetospeed(&ttbufs, ospeed);
146 for (ps = spds; ps->sp_val; ps++)
147 if (ps->sp_name == ospeed) {
148 spwant = ps->sp_val;
149 break;
150 }
151 }
152 ttbufs.c_iflag &= 0xffff0000;
153 ttbufs.c_oflag &= 0xffff0000;
154 ttbufs.c_lflag &= 0xffff0000;
155
156 ttbufs.c_cflag &= ~CLOCAL;
157
158 if (EQUALS(Progname, "cu")) {
159
160 /* set attributes associated with -h, -t, -e, and -o options */
161
162 ttbufs.c_iflag = (IGNPAR | IGNBRK | IXON | IXOFF);
163 if (line_8bit) {
164 ttbufs.c_cflag |= CS8;
165 ttbufs.c_iflag &= ~ISTRIP;
166 } else {
167 ttbufs.c_cflag |= CS7;
168 ttbufs.c_iflag |= ISTRIP;
169 }
170
171 ttbufs.c_cc[VEOF] = '\1';
172 ttbufs.c_cflag |= (CREAD | (speed ? HUPCL : 0));
173
174 if (Evenflag) { /* even parity -e */
175 if (ttbufs.c_cflag & PARENB) {
176 VERBOSE(P_PARITY, 0);
177 exit(1);
178 }
179 ttbufs.c_cflag |= PARENB;
180 } else if (Oddflag) { /* odd parity -o */
181 if (ttbufs.c_cflag & PARENB) {
182 VERBOSE(P_PARITY, 0);
183 exit(1);
184 }
185 ttbufs.c_cflag |= PARODD;
186 ttbufs.c_cflag |= PARENB;
187 }
188
189 if (!Duplex) /* half duplex -h */
190 ttbufs.c_iflag &= ~(IXON | IXOFF);
191 if (Terminal) /* -t */
192 ttbufs.c_oflag |= (OPOST | ONLCR);
193
194 } else { /* non-cu */
195 ttbufs.c_cflag |= (CS8 | CREAD | (speed ? HUPCL : 0));
196 ttbufs.c_cc[VMIN] = HEADERSIZE;
197 ttbufs.c_cc[VTIME] = 1;
198 }
199
200 if (istermios < 0) {
201 ttbuf.c_lflag = ttbufs.c_lflag;
202 ttbuf.c_oflag = ttbufs.c_oflag;
203 ttbuf.c_iflag = ttbufs.c_iflag;
204 ttbuf.c_cflag = ttbufs.c_cflag;
205 for (i = 0; i < NCC; i++)
206 ttbuf.c_cc[i] = ttbufs.c_cc[i];
207 ASSERT((*Ioctl)(tty, TCSETAW, &ttbuf) >= 0,
208 "RETURN FROM fixline ioctl", "", errno);
209 } else {
210 ASSERT((*Ioctl)(tty, TCSETSW, &ttbufs) >= 0,
211 "RETURN FROM fixline ioctl", "", errno);
212 }
213 }
214
215 static void
sethup(int dcf)216 sethup(int dcf)
217 {
218 struct termio ttbuf;
219
220 if ((*Ioctl)(dcf, TCGETA, &ttbuf) != 0)
221 return;
222 if (!(ttbuf.c_cflag & HUPCL)) {
223 ttbuf.c_cflag |= HUPCL;
224 (void) (*Ioctl)(dcf, TCSETAW, &ttbuf);
225 }
226 }
227
228 static void
ttygenbrk(int fn)229 ttygenbrk(int fn)
230 {
231 if (isatty(fn))
232 (void) (*Ioctl)(fn, TCSBRK, 0);
233 }
234
235 static int
savline(void)236 savline(void)
237 {
238 if ((Saved_termios = (*Ioctl)(0, TCGETS, &Savettybs)) < 0) {
239 if ((*Ioctl)(0, TCGETA, &Savettyb) != 0) {
240 Saved_line = FALSE;
241 } else {
242 Saved_line = TRUE;
243 Savettyb.c_cflag = (Savettyb.c_cflag & ~CS8) | CS7;
244 Savettyb.c_oflag |= OPOST;
245 Savettyb.c_lflag |= (ISIG|ICANON|ECHO);
246 }
247 } else {
248 Saved_line = TRUE;
249 Savettybs.c_cflag = (Savettybs.c_cflag & ~CS8) | CS7;
250 Savettybs.c_oflag |= OPOST;
251 Savettybs.c_lflag |= (ISIG|ICANON|ECHO);
252 }
253 return (0);
254 }
255
256 static int
restline(void)257 restline(void)
258 {
259 if (Saved_line == TRUE) {
260 if (Saved_termios < 0)
261 return ((*Ioctl)(0, TCSETAW, &Savettyb));
262 else
263 return ((*Ioctl)(0, TCSETSW, &Savettybs));
264 }
265 return (0);
266 }
267