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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1995 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 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 /* This is a new line.c, which consists of line.c and culine.c 34 * merged together. 35 */ 36 37 #include "uucp.h" 38 39 static struct sg_spds { 40 int sp_val, 41 sp_name; 42 } spds[] = { 43 { 50, B50}, 44 { 75, B75}, 45 { 110, B110}, 46 { 134, B134}, 47 { 150, B150}, 48 { 200, B200}, 49 { 300, B300}, 50 { 600, B600}, 51 {1200, B1200}, 52 {1800, B1800}, 53 {2400, B2400}, 54 {4800, B4800}, 55 {9600, B9600}, 56 #ifdef EXTA 57 {19200, EXTA}, 58 #endif 59 #ifdef B19200 60 {19200, B19200}, 61 #endif 62 #ifdef B38400 63 {38400, B38400}, 64 #endif 65 {57600, B57600}, 66 {76800, B76800}, 67 {115200, B115200}, 68 {153600, B153600}, 69 {230400, B230400}, 70 {307200, B307200}, 71 {460800, B460800}, 72 {0, 0} 73 }; 74 75 #define PACKSIZE 64 76 #define HEADERSIZE 6 77 78 GLOBAL int 79 packsize = PACKSIZE, 80 xpacksize = PACKSIZE; 81 82 #define SNDFILE 'S' 83 #define RCVFILE 'R' 84 #define RESET 'X' 85 86 #ifdef PKSPEEDUP 87 GLOBAL int linebaudrate; /* for speedup hook in pk1.c */ 88 #endif /* PKSPEEDUP */ 89 static int Saved_line; /* was savline() successful? */ 90 static int Saved_termios; /* was termios saved? */ 91 GLOBAL int 92 Oddflag = 0, /* Default is no parity */ 93 Evenflag = 0, /* Default is no parity */ 94 Duplex = 1, /* Default is full duplex */ 95 Terminal = 0, /* Default is no terminal */ 96 term_8bit = -1, /* Default to terminal setting or 8 bit */ 97 line_8bit = -1; /* Default is same as terminal */ 98 99 static char *P_PARITY = "Parity option error\r\n"; 100 101 #ifdef ATTSVTTY 102 103 static struct termio Savettyb; 104 static struct termios Savettybs; 105 /* 106 * set speed/echo/mode... 107 * tty -> terminal name 108 * spwant -> speed 109 * type -> type 110 * 111 * if spwant == 0, speed is untouched 112 * type is unused, but needed for compatibility 113 * 114 * return: 115 * none 116 */ 117 /*ARGSUSED*/ 118 GLOBAL void 119 fixline(tty, spwant, type) 120 int tty, spwant, type; 121 { 122 register struct sg_spds *ps; 123 struct termio ttbuf; 124 struct termios ttbufs; 125 int speed = -1; 126 int i, istermios, ospeed; 127 128 DEBUG(6, "fixline(%d, ", tty); 129 DEBUG(6, "%d)\n", spwant); 130 if ((istermios = (*Ioctl)(tty, TCGETS, &ttbufs)) < 0) { 131 if ((*Ioctl)(tty, TCGETA, &ttbuf) != 0) { 132 return; 133 } else { 134 ttbufs.c_lflag = ttbuf.c_lflag; 135 ttbufs.c_oflag = ttbuf.c_oflag; 136 ttbufs.c_iflag = ttbuf.c_iflag; 137 ttbufs.c_cflag = ttbuf.c_cflag; 138 for(i = 0; i < NCC; i++) 139 ttbufs.c_cc[i] = ttbuf.c_cc[i]; 140 } 141 } 142 if (spwant > 0) { 143 for (ps = spds; ps->sp_val; ps++) 144 if (ps->sp_val == spwant) { 145 speed = ps->sp_name; 146 break; 147 } 148 if ( speed < 0 ) 149 DEBUG(5, "speed (%d) not supported\n", spwant); 150 ASSERT(speed >= 0, "BAD SPEED", "", spwant); 151 ttbufs.c_cflag &= 0xffff0000; 152 cfsetospeed(&ttbufs, speed); 153 } else { /* determine the current speed setting */ 154 ospeed = cfgetospeed(&ttbufs); 155 ttbufs.c_cflag &= 0xffff0000; 156 cfsetospeed(&ttbufs, ospeed); 157 for (ps = spds; ps->sp_val; ps++) 158 if (ps->sp_name == ospeed) { 159 spwant = ps->sp_val; 160 break; 161 } 162 } 163 ttbufs.c_iflag &= 0xffff0000; 164 ttbufs.c_oflag &= 0xffff0000; 165 ttbufs.c_lflag &= 0xffff0000; 166 #ifdef PKSPEEDUP 167 linebaudrate = spwant; 168 #endif /* PKSPEEDUP */ 169 170 #ifdef NO_MODEM_CTRL 171 /* CLOCAL may cause problems on pdp11s with DHs */ 172 if (type == D_DIRECT) { 173 DEBUG(4, "fixline - direct\n%s", ""); 174 ttbufs.c_cflag |= CLOCAL; 175 } else 176 #endif /* NO_MODEM_CTRL */ 177 ttbufs.c_cflag &= ~CLOCAL; 178 179 if ( !EQUALS(Progname, "uucico") ) { 180 181 /* set attributes associated with -h, -t, -e, and -o options */ 182 183 ttbufs.c_iflag = (IGNPAR | IGNBRK | IXON | IXOFF); 184 ttbufs.c_cc[VEOF] = '\1'; 185 ttbufs.c_cflag |= ( CREAD | (speed ? HUPCL : 0)); 186 187 if ( line_8bit ) { 188 ttbufs.c_cflag |= CS8; 189 ttbufs.c_iflag &= ~ISTRIP; 190 } else { 191 if (Evenflag) { /*even parity -e */ 192 ttbufs.c_cflag &= ~PARODD; 193 } else if(Oddflag) { /*odd parity -o */ 194 ttbufs.c_cflag |= PARODD; 195 } 196 ttbufs.c_cflag |= CS7|PARENB; 197 ttbufs.c_iflag |= ISTRIP; 198 } 199 200 if(!Duplex) /*half duplex -h */ 201 ttbufs.c_iflag &= ~(IXON | IXOFF); 202 if(Terminal) /* -t */ 203 ttbufs.c_oflag |= (OPOST | ONLCR); 204 205 } else { /* non-uucico */ 206 ttbufs.c_cflag |= (CS8 | CREAD | (speed ? HUPCL : 0)); 207 ttbufs.c_cc[VMIN] = HEADERSIZE; 208 ttbufs.c_cc[VTIME] = 1; 209 } 210 211 if (istermios < 0) { 212 ttbuf.c_lflag = ttbufs.c_lflag; 213 ttbuf.c_oflag = ttbufs.c_oflag; 214 ttbuf.c_iflag = ttbufs.c_iflag; 215 ttbuf.c_cflag = ttbufs.c_cflag; 216 for(i = 0; i < NCC; i++) 217 ttbuf.c_cc[i] = ttbufs.c_cc[i]; 218 ASSERT((*Ioctl)(tty, TCSETAW, &ttbuf) >= 0, 219 "RETURN FROM fixline ioctl", "", errno); 220 } else { 221 ASSERT((*Ioctl)(tty, TCSETSW, &ttbufs) >= 0, 222 "RETURN FROM fixline ioctl", "", errno); 223 } 224 225 return; 226 } 227 228 GLOBAL void 229 sethup(dcf) 230 int dcf; 231 { 232 struct termio ttbuf; 233 234 if ((*Ioctl)(dcf, TCGETA, &ttbuf) != 0) 235 return; 236 if (!(ttbuf.c_cflag & HUPCL)) { 237 ttbuf.c_cflag |= HUPCL; 238 (void) (*Ioctl)(dcf, TCSETAW, &ttbuf); 239 } 240 return; 241 } 242 243 GLOBAL void 244 ttygenbrk(fn) 245 register int fn; 246 { 247 if (isatty(fn)) 248 (void) (*Ioctl)(fn, TCSBRK, 0); 249 return; 250 } 251 252 253 /* 254 * optimize line setting for sending or receiving files 255 * return: 256 * none 257 */ 258 GLOBAL void 259 setline(type) 260 register char type; 261 { 262 static struct termio tbuf; 263 static struct termios tbufs; 264 int i, vtime, istermios, ospeed; 265 266 DEBUG(2, "setline - %c\n", type); 267 268 if ((istermios = (*Ioctl)(Ifn, TCGETS, &tbufs)) < 0) { 269 if ((*Ioctl)(Ifn, TCGETA, &tbuf) != 0) { 270 return; 271 } else { 272 tbufs.c_lflag = tbuf.c_lflag; 273 tbufs.c_oflag = tbuf.c_oflag; 274 tbufs.c_iflag = tbuf.c_iflag; 275 tbufs.c_cflag = tbuf.c_cflag; 276 for(i = 0; i < NCC; i++) 277 tbufs.c_cc[i] = tbuf.c_cc[i]; 278 } 279 } 280 switch (type) { 281 case RCVFILE: 282 ospeed = cfgetospeed(&tbufs); 283 switch (ospeed) { 284 #ifdef B19200 285 case B19200: 286 #else 287 #ifdef EXTA 288 case EXTA: 289 #endif 290 #endif 291 #ifdef B38400 292 case B38400: 293 #endif 294 case B57600: 295 case B76800: 296 case B115200: 297 case B153600: 298 case B230400: 299 case B307200: 300 case B460800: 301 case B9600: 302 vtime = 1; 303 break; 304 case B4800: 305 vtime = 4; 306 break; 307 default: 308 vtime = 8; 309 break; 310 } 311 if (tbufs.c_cc[VMIN] != packsize || 312 tbufs.c_cc[VTIME] != vtime) { 313 tbufs.c_cc[VMIN] = packsize; 314 tbufs.c_cc[VTIME] = vtime; 315 if (istermios < 0) { 316 tbuf.c_lflag = tbufs.c_lflag; 317 tbuf.c_oflag = tbufs.c_oflag; 318 tbuf.c_iflag = tbufs.c_iflag; 319 tbuf.c_cflag = tbufs.c_cflag; 320 for(i = 0; i < NCC; i++) 321 tbuf.c_cc[i] = tbufs.c_cc[i]; 322 if ( (*Ioctl)(Ifn, TCSETAW, &tbuf) != 0 ) 323 DEBUG(4, "setline Ioctl failed errno=%d\n", errno); 324 } else { 325 if ( (*Ioctl)(Ifn, TCSETSW, &tbufs) != 0 ) 326 DEBUG(4, "setline Ioctl failed errno=%d\n", errno); 327 } 328 } 329 break; 330 331 case SNDFILE: 332 case RESET: 333 if (tbufs.c_cc[VMIN] != HEADERSIZE) { 334 tbufs.c_cc[VMIN] = HEADERSIZE; 335 if (istermios < 0) { 336 tbuf.c_lflag = tbufs.c_lflag; 337 tbuf.c_oflag = tbufs.c_oflag; 338 tbuf.c_iflag = tbufs.c_iflag; 339 tbuf.c_cflag = tbufs.c_cflag; 340 for(i = 0; i < NCC; i++) 341 tbuf.c_cc[i] = tbufs.c_cc[i]; 342 if ( (*Ioctl)(Ifn, TCSETAW, &tbuf) != 0 ) 343 DEBUG(4, "setline Ioctl failed errno=%d\n", errno); 344 } else { 345 if ( (*Ioctl)(Ifn, TCSETSW, &tbufs) != 0 ) 346 DEBUG(4, "setline Ioctl failed errno=%d\n", errno); 347 } 348 } 349 break; 350 } 351 return; 352 } 353 354 GLOBAL int 355 savline() 356 { 357 if ((Saved_termios = (*Ioctl)(0, TCGETS, &Savettybs)) < 0) { 358 if ( (*Ioctl)(0, TCGETA, &Savettyb) != 0 ) { 359 Saved_line = FALSE; 360 } else { 361 Saved_line = TRUE; 362 Savettyb.c_cflag = (Savettyb.c_cflag & ~CS8) | CS7 | PARENB; 363 Savettyb.c_oflag |= OPOST; 364 Savettyb.c_lflag |= (ISIG|ICANON|ECHO); 365 } 366 } else { 367 Saved_line = TRUE; 368 Savettybs.c_cflag = (Savettybs.c_cflag & ~CS8) | CS7 | PARENB; 369 Savettybs.c_oflag |= OPOST; 370 Savettybs.c_lflag |= (ISIG|ICANON|ECHO); 371 } 372 return(0); 373 } 374 375 #ifdef SYTEK 376 377 /* 378 * sytfixline(tty, spwant) set speed/echo/mode... 379 * int tty, spwant; 380 * 381 * return codes: none 382 */ 383 384 GLOBAL void 385 sytfixline(tty, spwant) 386 int tty, spwant; 387 { 388 struct termio ttbuf; 389 struct termios ttbufs; 390 struct sg_spds *ps; 391 int speed = -1; 392 int i, ret, istermios; 393 394 if ((istermios = (*Ioctl)(tty, TCGETS, &ttbufs)) < 0) { 395 if ( (*Ioctl)(tty, TCGETA, &ttbuf) != 0 ) { 396 return; 397 } else { 398 ttbufs.c_lflag = ttbuf.c_lflag; 399 ttbufs.c_oflag = ttbuf.c_oflag; 400 ttbufs.c_iflag = ttbuf.c_iflag; 401 ttbufs.c_cflag = ttbuf.c_cflag; 402 for(i = 0; i < NCC; i++) 403 ttbufs.c_cc[i] = ttbuf.c_cc[i]; 404 } 405 } 406 for (ps = spds; ps->sp_val >= 0; ps++) 407 if (ps->sp_val == spwant) 408 speed = ps->sp_name; 409 DEBUG(4, "sytfixline - speed= %d\n", speed); 410 ASSERT(speed >= 0, "BAD SPEED", "", spwant); 411 ttbufs.c_iflag &= 0xffff0000; 412 ttbufs.c_oflag &= 0xffff0000; 413 ttbufs.c_lflag &= 0xffff0000; 414 ttbufs.c_cflag &= 0xffff0000; 415 cfsetospeed(&ttbufs, speed); 416 ttbufs.c_cflag |= (CS8|CLOCAL); 417 ttbufs.c_cc[VMIN] = 6; 418 ttbufs.c_cc[VTIME] = 1; 419 if (istermios < 0) { 420 ttbuf.c_lflag = ttbufs.c_lflag; 421 ttbuf.c_oflag = ttbufs.c_oflag; 422 ttbuf.c_iflag = ttbufs.c_iflag; 423 ttbuf.c_cflag = ttbufs.c_cflag; 424 for(i = 0; i < NCC; i++) 425 ttbuf.c_cc[i] = ttbufs.c_cc[i]; 426 ret = (*Ioctl)(tty, TCSETAW, &ttbuf); 427 } else 428 ret = (*Ioctl)(tty, TCSETAWS &ttbufs); 429 ASSERT(ret >= 0, "RETURN FROM sytfixline", "", ret); 430 return; 431 } 432 433 GLOBAL void 434 sytfix2line(tty) 435 int tty; 436 { 437 struct termio ttbuf; 438 int ret; 439 440 if ( (*Ioctl)(tty, TCGETA, &ttbuf) != 0 ) 441 return; 442 ttbuf.c_cflag &= ~CLOCAL; 443 ttbuf.c_cflag |= CREAD|HUPCL; 444 ret = (*Ioctl)(tty, TCSETAW, &ttbuf); 445 ASSERT(ret >= 0, "RETURN FROM sytfix2line", "", ret); 446 return; 447 } 448 449 #endif /* SYTEK */ 450 451 GLOBAL int 452 restline() 453 { 454 if ( Saved_line == TRUE ) { 455 if (Saved_termios < 0) 456 return((*Ioctl)(0, TCSETAW, &Savettyb)); 457 else 458 return((*Ioctl)(0, TCSETSW, &Savettybs)); 459 } 460 return(0); 461 } 462 463 #else /* !ATTSVTTY */ 464 465 static struct sgttyb Savettyb; 466 467 /* 468 * fixline(tty, spwant, type) set speed/echo/mode... 469 * int tty, spwant; 470 * 471 * if spwant == 0, speed is untouched 472 * type is unused, but needed for compatibility 473 * 474 * return codes: none 475 */ 476 477 /*ARGSUSED*/ 478 GLOBAL void 479 fixline(tty, spwant, type) 480 int tty, spwant, type; 481 { 482 struct sgttyb ttbuf; 483 struct sg_spds *ps; 484 int speed = -1; 485 486 DEBUG(6, "fixline(%d, ", tty); 487 DEBUG(6, "%d)\n", spwant); 488 489 if ((*Ioctl)(tty, TIOCGETP, &ttbuf) != 0) 490 return; 491 if (spwant > 0) { 492 for (ps = spds; ps->sp_val; ps++) 493 if (ps->sp_val == spwant) { 494 speed = ps->sp_name; 495 break; 496 } 497 ASSERT(speed >= 0, "BAD SPEED", "", spwant); 498 ttbuf.sg_ispeed = ttbuf.sg_ospeed = speed; 499 } else { 500 for (ps = spds; ps->sp_val; ps++) 501 if (ps->sp_name == ttbuf.sg_ispeed) { 502 spwant = ps->sp_val; 503 break; 504 } 505 ASSERT(spwant >= 0, "BAD SPEED", "", ttbuf.sg_ispeed); 506 } 507 ttbuf.sg_flags = (ANYP | RAW); 508 #ifdef PKSPEEDUP 509 linebaudrate = spwant; 510 #endif /* PKSPEEDUP */ 511 (void) (*Ioctl)(tty, TIOCSETP, &ttbuf); 512 (void) (*Ioctl)(tty, TIOCHPCL, STBNULL); 513 (void) (*Ioctl)(tty, TIOCEXCL, STBNULL); 514 return; 515 } 516 517 GLOBAL void 518 sethup(dcf) 519 int dcf; 520 { 521 if (isatty(dcf)) 522 (void) (*Ioctl)(dcf, TIOCHPCL, STBNULL); 523 return; 524 } 525 526 /* 527 * genbrk send a break 528 * 529 * return codes; none 530 */ 531 532 GLOBAL void 533 ttygenbrk(fn) 534 { 535 if (isatty(fn)) { 536 (void) (*Ioctl)(fn, TIOCSBRK, 0); 537 #ifndef V8 538 nap(HZ/10); /* 0.1 second break */ 539 (void) (*Ioctl)(fn, TIOCCBRK, 0); 540 #endif 541 } 542 return; 543 } 544 545 /* 546 * V7 and RT aren't smart enough for this -- linebaudrate is the best 547 * they can do. 548 */ 549 /*ARGSUSED*/ 550 GLOBAL void 551 setline(dummy) { } 552 553 GLOBAL int 554 savline() 555 { 556 if ( (*Ioctl)(0, TIOCGETP, &Savettyb) != 0 ) 557 Saved_line = FALSE; 558 else { 559 Saved_line = TRUE; 560 Savettyb.sg_flags |= ECHO; 561 Savettyb.sg_flags &= ~RAW; 562 } 563 return(0); 564 } 565 566 GLOBAL int 567 restline() 568 { 569 if ( Saved_line == TRUE ) 570 return((*Ioctl)(0, TIOCSETP, &Savettyb)); 571 return(0); 572 } 573 #endif 574