You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
bforce/source/bforce/io_unix_tio.c

337 lines
5.9 KiB
C

/*
* binkleyforce -- unix FTN mailer project
*
* Copyright (c) 1998-2000 Alexander Belkin, 2:5020/1398.11
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* $Id$
*/
#include "includes.h"
#include "confread.h"
#include "logger.h"
#include "util.h"
#include "io.h"
/*
* Hardware handshake flags (stolen from mgetty)
*/
#ifdef CRTSCTS
# define TIO_FLOW_HARD CRTSCTS /* linux, SunOS */
#else
# ifdef CRTSFL
# define TIO_FLOW_HARD CRTSFL /* SCO 3.2v4.2 */
# else
# ifdef RTSFLOW
# define TIO_FLOW_HARD RTSFLOW | CTSFLOW /* SCO 3.2v2 */
# else
# ifdef CTSCD
# define TIO_FLOW_HARD CTSCD /* AT&T 3b1? */
# else
# define TIO_FLOW_HARD 0
# endif
# endif
# endif
#endif
/*
* Software hadshake flags
*/
#define TIO_FLOW_SOFT (IXON | IXOFF)
/*
* Supported baud rates
*/
static struct speedtab {
#ifdef HAVE_TERMIOS_H
speed_t bspeed;
#else
unsigned short bspeed;
#endif
int nspeed;
const char *speed;
} speedtab[] = {
{ B300, 300, "300" },
#ifdef B600
{ B600, 600, "600" },
#endif
#ifdef B900
{ B900, 900, "900" },
#endif
{ B1200, 1200, "1200" },
#ifdef B1800
{ B1800, 1800, "1800" },
#endif
{ B2400, 2400, "2400" },
#ifdef B3600
{ B3600, 3600, "3600" },
#endif
{ B4800, 4800, "4800" },
#ifdef B7200
{ B7200, 7200, "7200" },
#endif
{ B9600, 9600, "9600" },
#ifdef B14400
{ B14400, 14400, "14400" },
#endif
#ifdef B19200
{ B19200, 19200, "19200" },
#endif /* B19200 */
#ifdef B28800
{ B28800, 28800, "28800" },
#endif
#ifdef B38400
{ B38400, 38400, "38400" },
#endif /* B38400 */
#ifdef EXTA
{ EXTA, 19200, "EXTA" },
#endif
#ifdef EXTB
{ EXTB, 38400, "EXTB" },
#endif
#ifdef B57600
{ B57600, 57600, "57600" },
#endif
#ifdef B76800
{ B76800, 76800, "76800" },
#endif
#ifdef B115200
{ B115200, 115200, "115200" },
#endif
#ifdef B230400
{ B230400, 230400, "230400" },
#endif
#ifdef B460800
{ B460800, 460800, "460800" },
#endif
{ 0, 0, "" }
};
/* get current tio settings for given filedescriptor */
int tio_get(int fd, TIO *tio)
{
#ifdef HAVE_TERMIOS_H
return tcgetattr(fd, tio);
#endif
}
/* set current tio settings for given filedescriptor */
int tio_set(int fd, TIO *tio)
{
#ifdef HAVE_TERMIOS_H
return tcsetattr(fd, TCSANOW, tio);
#endif
}
int tio_set_speed(TIO *tio, unsigned int speed)
{
int i;
#ifdef HAVE_TERMIOS_H
speed_t bspeed = -1;
#else
int bspeed = -1;
#endif
for( i = 0; speedtab[i].nspeed; i++ )
{
if( speedtab[i].nspeed == speed )
{
bspeed = speedtab[i].bspeed;
break;
}
}
if( bspeed == -1 )
{
log("unsupported speed %d", speed);
return -1;
}
#ifdef HAVE_TERMIOS_H
cfsetospeed(tio, bspeed);
cfsetispeed(tio, bspeed);
#endif
return 0;
}
/* get port speed. Return integer value, not symbolic constant */
int tio_get_speed(TIO *tio)
{
int i;
#ifdef HAVE_TERMIOS_H
speed_t bspeed = cfgetospeed(tio);
#endif
for( i = 0; speedtab[i].nspeed; i++ )
{
if( speedtab[i].bspeed == bspeed )
return speedtab[i].nspeed;
}
return-1;
}
int tio_set_flow_control(int fd, TIO *tio, int flow)
{
#if defined(HAVE_SYS_TERMIOX_H)
struct termiox tix;
#endif
DEB((D_MODEM, "tio_set_flow_control: setting HARD=%s, SOFT=%s",
(flow & FLOW_HARD) ? "On" : "Off",
(flow & FLOW_SOFT) ? "On" : "Off"));
#if defined(HAVE_TERMIOS_H)
tio->c_cflag &= ~TIO_FLOW_HARD;
tio->c_iflag &= ~TIO_FLOW_SOFT;
#ifdef IXANY
tio->c_iflag &= ~IXANY;
#endif
if( flow & FLOW_HARD )
tio->c_cflag |= TIO_FLOW_HARD;
if( flow & FLOW_SOFT )
tio->c_iflag |= TIO_FLOW_SOFT;
#endif /* HAVE_TERMIOS_H */
#if defined(HAVE_SYS_TERMIOX_H)
if( ioctl(fd, TCGETX, &tix) == -1 )
{
logerr("failed ioctl(TCGETX)");
return -1;
}
if( flow & FLOW_HARD )
tix.x_hflag |= (RTSXOFF | CTSXON);
else
tix.x_hflag &= ~(RTSXOFF | CTSXON);
if( ioctl(fd, TCSETX, &tix) == -1 )
{
logerr("failed ioctl(TCSETX)");
return -1;
}
#endif /* HAVE_SYS_TERMIOX_H */
return 0;
}
void tio_set_raw_mode(TIO *tio)
{
#if defined(HAVE_TERMIOS_H)
tio->c_cflag &= ~(CSTOPB | PARENB | PARODD);
tio->c_cflag |= (CS8 | CREAD | HUPCL);
tio->c_iflag = TIO_FLOW_SOFT;
tio->c_oflag = 0;
tio->c_lflag = 0;
tio->c_cc[VMIN] = 128;
tio->c_cc[VTIME] = 1;
#endif
}
void tio_set_local(TIO *tio, bool local)
{
#if defined(HAVE_TERMIOS_H)
if( local )
tio->c_cflag |= CLOCAL;
else
tio->c_cflag &= ~CLOCAL;
#endif
}
int tio_set_dtr(int fd, bool on)
{
int mctl = TIO_RS232_DTR;
DEB((D_MODEM, "tio_setdtr: setting DTR = %s", on ? "On" : "Off"));
if( on )
{
if( ioctl(fd, TIOCMBIS, &mctl ) < 0 )
{
logerr("cannot set DTR = On: TIOCMBIS failed");
return -1;
}
}
else
{
if( ioctl(fd, TIOCMBIC, &mctl ) < 0 )
{
logerr("cannot set DTR = Off: TIOCMBIC failed");
return -1;
}
}
return 0;
}
int tio_ctty(int fd)
{
if( setsid() < 0 )
logerr("cannot make myself session leader (setsid)");
#ifdef TIOCSCTTY
if( ioctl(fd, TIOCSCTTY, 0) < 0 )
{
logerr("cannot set controlling tty (ioctl)");
return -1;
}
#endif
return 0;
}
int tio_send_break(void)
{
#ifdef HAVE_TERMIOS_H
if( tcsendbreak(1, 0) < 0 )
{
logerr("tcsendbreak(1,0) failed");
#else
if( ioctl(1, TCSBRK) < 0 )
{
logerr("ioctl(1,TCSBRK) failed");
#endif
return -1;
}
return 0;
}
int tio_get_dcd(int fd)
{
int flags;
if( ioctl(fd, TIOCMGET, &flags ) < 0 )
return -1;
return (flags & TIO_RS232_DCD) ? 1 : 0;
}
int tio_get_rs232_state(void)
{
int flags;
if( ioctl(0, TIOCMGET, &flags ) < 0 )
return -1;
DEB((D_MODEM, "tio_getrs232: [%s]-[%s]-[%s]-[%s]-[%s]-[%s]",
( flags & TIO_RS232_RTS ) ? "RTS" : "rts",
( flags & TIO_RS232_CTS ) ? "CTS" : "cts",
( flags & TIO_RS232_DSR ) ? "DSR" : "dsr",
( flags & TIO_RS232_DTR ) ? "DTR" : "dtr",
( flags & TIO_RS232_DCD ) ? "DCD" : "dcd",
( flags & TIO_RS232_RNG ) ? "RNG" : "rng"));
return flags;
}