2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A
2N/A/*
2N/A * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A */
2N/A
2N/A/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
2N/A/* All Rights Reserved */
2N/A
2N/A/*
2N/A * This is a new line.c, which consists of line.c and culine.c
2N/A * merged together.
2N/A */
2N/A
2N/A#include "mt.h"
2N/A#include "uucp.h"
2N/A
2N/Astatic const struct sg_spds {
2N/A int sp_val,
2N/A sp_name;
2N/A} spds[] = {
2N/A { 50, B50},
2N/A { 75, B75},
2N/A { 110, B110},
2N/A { 134, B134},
2N/A { 150, B150},
2N/A { 200, B200},
2N/A { 300, B300},
2N/A { 600, B600},
2N/A {1200, B1200},
2N/A {1800, B1800},
2N/A {2400, B2400},
2N/A {4800, B4800},
2N/A {9600, B9600},
2N/A#ifdef EXTA
2N/A {19200, EXTA},
2N/A#endif
2N/A#ifdef B19200
2N/A {19200, B19200},
2N/A#endif
2N/A#ifdef B38400
2N/A {38400, B38400},
2N/A#endif
2N/A {57600, B57600},
2N/A {76800, B76800},
2N/A {115200, B115200},
2N/A {153600, B153600},
2N/A {230400, B230400},
2N/A {307200, B307200},
2N/A {460800, B460800},
2N/A {921600, B921600},
2N/A {0, 0}
2N/A};
2N/A
2N/A#define PACKSIZE 64
2N/A#define HEADERSIZE 6
2N/A
2N/A#define SNDFILE 'S'
2N/A#define RCVFILE 'R'
2N/A#define RESET 'X'
2N/A
2N/Astatic int Saved_line; /* was savline() successful? */
2N/Astatic int Saved_termios; /* was termios saved? */
2N/Astatic int
2N/A Oddflag, /* Default is no parity */
2N/A Evenflag, /* Default is no parity */
2N/A Duplex = 1, /* Default is full duplex */
2N/A Terminal, /* Default is no terminal */
2N/A line_8bit = -1; /* Default is same as terminal */
2N/A
2N/Astatic const char P_PARITY[] = "Parity option error\r\n";
2N/A
2N/Astatic struct termio Savettyb;
2N/Astatic struct termios Savettybs;
2N/A/*
2N/A * set speed/echo/mode...
2N/A * tty -> terminal name
2N/A * spwant -> speed
2N/A * type -> type
2N/A *
2N/A * if spwant == 0, speed is untouched
2N/A * type is unused, but needed for compatibility
2N/A *
2N/A * return:
2N/A * none
2N/A */
2N/A/*ARGSUSED*/
2N/Astatic void
2N/Afixline(int tty, int spwant, int type)
2N/A{
2N/A register const struct sg_spds *ps;
2N/A struct termio ttbuf;
2N/A struct termios ttbufs;
2N/A int speed = -1;
2N/A int i, istermios, ospeed;
2N/A
2N/A DEBUG(6, "fixline(%d, ", tty);
2N/A DEBUG(6, "%d)\n", spwant);
2N/A if ((istermios = (*Ioctl)(tty, TCGETS, &ttbufs)) < 0) {
2N/A if ((*Ioctl)(tty, TCGETA, &ttbuf) != 0)
2N/A return;
2N/A ttbufs.c_lflag = ttbuf.c_lflag;
2N/A ttbufs.c_oflag = ttbuf.c_oflag;
2N/A ttbufs.c_iflag = ttbuf.c_iflag;
2N/A ttbufs.c_cflag = ttbuf.c_cflag;
2N/A for (i = 0; i < NCC; i++)
2N/A ttbufs.c_cc[i] = ttbuf.c_cc[i];
2N/A }
2N/A if (spwant > 0) {
2N/A for (ps = spds; ps->sp_val; ps++)
2N/A if (ps->sp_val == spwant) {
2N/A speed = ps->sp_name;
2N/A break;
2N/A }
2N/A if (speed < 0) {
2N/A /*EMPTY*/
2N/A DEBUG(5, "speed (%d) not supported\n", spwant);
2N/A }
2N/A ASSERT(speed >= 0, "BAD SPEED", "", spwant);
2N/A ttbufs.c_cflag &= 0xffff0000;
2N/A (void) cfsetospeed(&ttbufs, speed);
2N/A } else { /* determine the current speed setting */
2N/A ospeed = cfgetospeed(&ttbufs);
2N/A ttbufs.c_cflag &= 0xffff0000;
2N/A (void) cfsetospeed(&ttbufs, ospeed);
2N/A for (ps = spds; ps->sp_val; ps++)
2N/A if (ps->sp_name == ospeed) {
2N/A spwant = ps->sp_val;
2N/A break;
2N/A }
2N/A }
2N/A ttbufs.c_iflag &= 0xffff0000;
2N/A ttbufs.c_oflag &= 0xffff0000;
2N/A ttbufs.c_lflag &= 0xffff0000;
2N/A
2N/A ttbufs.c_cflag &= ~CLOCAL;
2N/A
2N/A if (EQUALS(Progname, "cu")) {
2N/A
2N/A /* set attributes associated with -h, -t, -e, and -o options */
2N/A
2N/A ttbufs.c_iflag = (IGNPAR | IGNBRK | IXON | IXOFF);
2N/A if (line_8bit) {
2N/A ttbufs.c_cflag |= CS8;
2N/A ttbufs.c_iflag &= ~ISTRIP;
2N/A } else {
2N/A ttbufs.c_cflag |= CS7;
2N/A ttbufs.c_iflag |= ISTRIP;
2N/A }
2N/A
2N/A ttbufs.c_cc[VEOF] = '\1';
2N/A ttbufs.c_cflag |= (CREAD | (speed ? HUPCL : 0));
2N/A
2N/A if (Evenflag) { /* even parity -e */
2N/A if (ttbufs.c_cflag & PARENB) {
2N/A VERBOSE(P_PARITY, 0);
2N/A exit(1);
2N/A }
2N/A ttbufs.c_cflag |= PARENB;
2N/A } else if (Oddflag) { /* odd parity -o */
2N/A if (ttbufs.c_cflag & PARENB) {
2N/A VERBOSE(P_PARITY, 0);
2N/A exit(1);
2N/A }
2N/A ttbufs.c_cflag |= PARODD;
2N/A ttbufs.c_cflag |= PARENB;
2N/A }
2N/A
2N/A if (!Duplex) /* half duplex -h */
2N/A ttbufs.c_iflag &= ~(IXON | IXOFF);
2N/A if (Terminal) /* -t */
2N/A ttbufs.c_oflag |= (OPOST | ONLCR);
2N/A
2N/A } else { /* non-cu */
2N/A ttbufs.c_cflag |= (CS8 | CREAD | (speed ? HUPCL : 0));
2N/A ttbufs.c_cc[VMIN] = HEADERSIZE;
2N/A ttbufs.c_cc[VTIME] = 1;
2N/A }
2N/A
2N/A if (istermios < 0) {
2N/A ttbuf.c_lflag = ttbufs.c_lflag;
2N/A ttbuf.c_oflag = ttbufs.c_oflag;
2N/A ttbuf.c_iflag = ttbufs.c_iflag;
2N/A ttbuf.c_cflag = ttbufs.c_cflag;
2N/A for (i = 0; i < NCC; i++)
2N/A ttbuf.c_cc[i] = ttbufs.c_cc[i];
2N/A ASSERT((*Ioctl)(tty, TCSETAW, &ttbuf) >= 0,
2N/A "RETURN FROM fixline ioctl", "", errno);
2N/A } else {
2N/A ASSERT((*Ioctl)(tty, TCSETSW, &ttbufs) >= 0,
2N/A "RETURN FROM fixline ioctl", "", errno);
2N/A }
2N/A}
2N/A
2N/Astatic void
2N/Asethup(int dcf)
2N/A{
2N/A struct termio ttbuf;
2N/A
2N/A if ((*Ioctl)(dcf, TCGETA, &ttbuf) != 0)
2N/A return;
2N/A if (!(ttbuf.c_cflag & HUPCL)) {
2N/A ttbuf.c_cflag |= HUPCL;
2N/A (void) (*Ioctl)(dcf, TCSETAW, &ttbuf);
2N/A }
2N/A}
2N/A
2N/Astatic void
2N/Attygenbrk(int fn)
2N/A{
2N/A if (isatty(fn))
2N/A (void) (*Ioctl)(fn, TCSBRK, 0);
2N/A}
2N/A
2N/Astatic int
2N/Asavline(void)
2N/A{
2N/A if ((Saved_termios = (*Ioctl)(0, TCGETS, &Savettybs)) < 0) {
2N/A if ((*Ioctl)(0, TCGETA, &Savettyb) != 0) {
2N/A Saved_line = FALSE;
2N/A } else {
2N/A Saved_line = TRUE;
2N/A Savettyb.c_cflag = (Savettyb.c_cflag & ~CS8) | CS7;
2N/A Savettyb.c_oflag |= OPOST;
2N/A Savettyb.c_lflag |= (ISIG|ICANON|ECHO);
2N/A }
2N/A } else {
2N/A Saved_line = TRUE;
2N/A Savettybs.c_cflag = (Savettybs.c_cflag & ~CS8) | CS7;
2N/A Savettybs.c_oflag |= OPOST;
2N/A Savettybs.c_lflag |= (ISIG|ICANON|ECHO);
2N/A }
2N/A return (0);
2N/A}
2N/A
2N/Astatic int
2N/Arestline(void)
2N/A{
2N/A if (Saved_line == TRUE) {
2N/A if (Saved_termios < 0)
2N/A return ((*Ioctl)(0, TCSETAW, &Savettyb));
2N/A else
2N/A return ((*Ioctl)(0, TCSETSW, &Savettybs));
2N/A }
2N/A return (0);
2N/A}