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 int 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 { 19200, B19200 },
56 { 38400, B38400 },
57 { 57600, B57600 },
58 { 76800, B76800 },
59 { 115200, B115200 },
60 { 153600, B153600 },
61 { 230400, B230400 },
62 { 307200, B307200 },
63 { 460800, B460800 },
64 { 921600, B921600 },
65 { 1000000, B1000000 },
66 { 1152000, B1152000 },
67 { 1500000, B1500000 },
68 { 2000000, B2000000 },
69 { 2500000, B2500000 },
70 { 3000000, B3000000 },
71 { 3500000, B3500000 },
72 { 4000000, B4000000 },
73 { 0, 0}
74 };
75
76 #define HEADERSIZE 6
77
78 static int Saved_line; /* was savline() successful? */
79 static int Saved_termios; /* was termios saved? */
80 static int
81 Oddflag, /* Default is no parity */
82 Evenflag, /* Default is no parity */
83 Duplex = 1, /* Default is full duplex */
84 Terminal, /* Default is no terminal */
85 line_8bit = -1; /* Default is same as terminal */
86
87 static const char P_PARITY[] = "Parity option error\r\n";
88
89 static struct termio Savettyb;
90 static struct termios Savettybs;
91 /*
92 * set speed/echo/mode...
93 * tty -> terminal name
94 * spwant -> speed
95 * type -> type
96 *
97 * if spwant == 0, speed is untouched
98 * type is unused, but needed for compatibility
99 *
100 * return:
101 * none
102 */
103 /*ARGSUSED*/
104 static void
fixline(int tty,int spwant,int type)105 fixline(int tty, int spwant, int type)
106 {
107 register const struct sg_spds *ps;
108 struct termio ttbuf;
109 struct termios ttbufs;
110 int speed = -1;
111 int i, istermios, ospeed;
112
113 DEBUG(6, "fixline(%d, ", tty);
114 DEBUG(6, "%d)\n", spwant);
115 if ((istermios = (*Ioctl)(tty, TCGETS, &ttbufs)) < 0) {
116 if ((*Ioctl)(tty, TCGETA, &ttbuf) != 0)
117 return;
118 ttbufs.c_lflag = ttbuf.c_lflag;
119 ttbufs.c_oflag = ttbuf.c_oflag;
120 ttbufs.c_iflag = ttbuf.c_iflag;
121 ttbufs.c_cflag = ttbuf.c_cflag;
122 for (i = 0; i < NCC; i++)
123 ttbufs.c_cc[i] = ttbuf.c_cc[i];
124 }
125 if (spwant > 0) {
126 for (ps = spds; ps->sp_val != 0; ps++)
127 if (ps->sp_val == spwant) {
128 speed = ps->sp_name;
129 break;
130 }
131 if (speed < 0) {
132 /*EMPTY*/
133 DEBUG(5, "speed (%d) not supported\n", spwant);
134 }
135 ASSERT(speed >= 0, "BAD SPEED", "", spwant);
136 ttbufs.c_cflag &= 0xffff0000;
137 (void) cfsetospeed(&ttbufs, speed);
138 } else { /* determine the current speed setting */
139 ospeed = cfgetospeed(&ttbufs);
140 ttbufs.c_cflag &= 0xffff0000;
141 (void) cfsetospeed(&ttbufs, ospeed);
142 for (ps = spds; ps->sp_val != 0; ps++)
143 if (ps->sp_name == ospeed) {
144 spwant = ps->sp_val;
145 break;
146 }
147 }
148 ttbufs.c_iflag &= 0xffff0000;
149 ttbufs.c_oflag &= 0xffff0000;
150 ttbufs.c_lflag &= 0xffff0000;
151
152 ttbufs.c_cflag &= ~CLOCAL;
153
154 if (EQUALS(Progname, "cu")) {
155
156 /* set attributes associated with -h, -t, -e, and -o options */
157
158 ttbufs.c_iflag = (IGNPAR | IGNBRK | IXON | IXOFF);
159 if (line_8bit) {
160 ttbufs.c_cflag |= CS8;
161 ttbufs.c_iflag &= ~ISTRIP;
162 } else {
163 ttbufs.c_cflag |= CS7;
164 ttbufs.c_iflag |= ISTRIP;
165 }
166
167 ttbufs.c_cc[VEOF] = '\1';
168 ttbufs.c_cflag |= (CREAD | (speed ? HUPCL : 0));
169
170 if (Evenflag) { /* even parity -e */
171 if (ttbufs.c_cflag & PARENB) {
172 VERBOSE(P_PARITY, 0);
173 exit(1);
174 }
175 ttbufs.c_cflag |= PARENB;
176 } else if (Oddflag) { /* odd parity -o */
177 if (ttbufs.c_cflag & PARENB) {
178 VERBOSE(P_PARITY, 0);
179 exit(1);
180 }
181 ttbufs.c_cflag |= PARODD;
182 ttbufs.c_cflag |= PARENB;
183 }
184
185 if (!Duplex) /* half duplex -h */
186 ttbufs.c_iflag &= ~(IXON | IXOFF);
187 if (Terminal) /* -t */
188 ttbufs.c_oflag |= (OPOST | ONLCR);
189
190 } else { /* non-cu */
191 ttbufs.c_cflag |= (CS8 | CREAD | (speed ? HUPCL : 0));
192 ttbufs.c_cc[VMIN] = HEADERSIZE;
193 ttbufs.c_cc[VTIME] = 1;
194 }
195
196 if (istermios < 0) {
197 ttbuf.c_lflag = ttbufs.c_lflag;
198 ttbuf.c_oflag = ttbufs.c_oflag;
199 ttbuf.c_iflag = ttbufs.c_iflag;
200 ttbuf.c_cflag = ttbufs.c_cflag;
201 for (i = 0; i < NCC; i++)
202 ttbuf.c_cc[i] = ttbufs.c_cc[i];
203 ASSERT((*Ioctl)(tty, TCSETAW, &ttbuf) >= 0,
204 "RETURN FROM fixline ioctl", "", errno);
205 } else {
206 ASSERT((*Ioctl)(tty, TCSETSW, &ttbufs) >= 0,
207 "RETURN FROM fixline ioctl", "", errno);
208 }
209 }
210
211 static void
sethup(int dcf)212 sethup(int dcf)
213 {
214 struct termio ttbuf;
215
216 if ((*Ioctl)(dcf, TCGETA, &ttbuf) != 0)
217 return;
218 if (!(ttbuf.c_cflag & HUPCL)) {
219 ttbuf.c_cflag |= HUPCL;
220 (void) (*Ioctl)(dcf, TCSETAW, &ttbuf);
221 }
222 }
223
224 static void
ttygenbrk(int fn)225 ttygenbrk(int fn)
226 {
227 if (isatty(fn))
228 (void) (*Ioctl)(fn, TCSBRK, 0);
229 }
230
231 static int
savline(void)232 savline(void)
233 {
234 if ((Saved_termios = (*Ioctl)(0, TCGETS, &Savettybs)) < 0) {
235 if ((*Ioctl)(0, TCGETA, &Savettyb) != 0) {
236 Saved_line = FALSE;
237 } else {
238 Saved_line = TRUE;
239 Savettyb.c_cflag = (Savettyb.c_cflag & ~CS8) | CS7;
240 Savettyb.c_oflag |= OPOST;
241 Savettyb.c_lflag |= (ISIG|ICANON|ECHO);
242 }
243 } else {
244 Saved_line = TRUE;
245 Savettybs.c_cflag = (Savettybs.c_cflag & ~CS8) | CS7;
246 Savettybs.c_oflag |= OPOST;
247 Savettybs.c_lflag |= (ISIG|ICANON|ECHO);
248 }
249 return (0);
250 }
251
252 static int
restline(void)253 restline(void)
254 {
255 if (Saved_line == TRUE) {
256 if (Saved_termios < 0)
257 return ((*Ioctl)(0, TCSETAW, &Savettyb));
258 else
259 return ((*Ioctl)(0, TCSETSW, &Savettybs));
260 }
261 return (0);
262 }
263