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.
243 lines
4.5 KiB
C
243 lines
4.5 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"
|
|
|
|
/*
|
|
* Get verbal device name, remove "/dev/" part and replace all '/'
|
|
* characters by the '-' character. Returned value must be freed.
|
|
*/
|
|
char *port_get_name(const char *devname)
|
|
{
|
|
char *yield = NULL;
|
|
|
|
if( !devname )
|
|
yield = xstrcpy("unknown");
|
|
else if( !strncmp(devname, "/dev/", 5) )
|
|
yield = xstrcpy(devname + 5);
|
|
else
|
|
yield = xstrcpy(devname);
|
|
|
|
string_replchar(yield, '/', '-');
|
|
|
|
return yield;
|
|
}
|
|
|
|
#ifndef MODEM_WATCH_CARRIER
|
|
static RETSIGTYPE linedrop(int sig)
|
|
{
|
|
if( tty_online )
|
|
{
|
|
log("carrier lost");
|
|
tty_hangup = TRUE;
|
|
}
|
|
else
|
|
{
|
|
log("terminating on signal %d", sig);
|
|
tty_abort = TRUE;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
static RETSIGTYPE interrupt(int sig)
|
|
{
|
|
tty_abort = TRUE;
|
|
log("terminating on signal %d", sig);
|
|
}
|
|
|
|
/*
|
|
* Open modem device $port, save old termios to $oldtio
|
|
*/
|
|
int port_open(const s_modemport *port, int detach, TIO *oldtio)
|
|
{
|
|
int fd;
|
|
|
|
ASSERT(port != NULL);
|
|
|
|
DEB((D_MODEM, "openport: open device \"%s\" locked at %ld",
|
|
port->name, (long)port->speed));
|
|
|
|
if( (fd = open(port->name, O_RDWR | O_NONBLOCK)) < 0 )
|
|
{ logerr("cannot open device \"%s\"", port->name); return 1; }
|
|
|
|
/* make new fd == stdin if it isn't already */
|
|
if( fd > 0 )
|
|
{
|
|
if( detach )
|
|
(void)close(0);
|
|
if( dup(fd) != 0 )
|
|
{ logerr("cannot make device \"%s\" stdin", port->name); return(1); }
|
|
}
|
|
|
|
/* make stdout and stderr, too */
|
|
if( detach )
|
|
{ (void)close(1); (void)close(2); }
|
|
|
|
if( dup(0) != 1 )
|
|
{ logerr("cannot dup stdin to stdout"); return(1); }
|
|
|
|
if( dup(0) != 2 )
|
|
{ logerr("cannot dup stdin to stderr"); return(1); }
|
|
|
|
if( fd > 2 )
|
|
(void)close(fd);
|
|
|
|
/* Set port modes (LOCAL mode) */
|
|
if( port_init(0, port->speed, oldtio, TRUE) )
|
|
return(1);
|
|
|
|
/* Make it controlling tty */
|
|
if( detach )
|
|
tio_ctty(0);
|
|
|
|
/*
|
|
* Switch off stdio buffering. We are
|
|
* not going to use streamed I/O, but..
|
|
*/
|
|
setbuf(stdin, (char *)NULL);
|
|
setbuf(stdout, (char *)NULL);
|
|
setbuf(stderr, (char *)NULL);
|
|
|
|
return(0);
|
|
}
|
|
|
|
/*
|
|
* Set terminal options as required. Don't forget that settings of
|
|
* the file descriptor copies made with dup() are shared.
|
|
*/
|
|
int port_init(int fd, int portspeed, TIO *oldtio, bool local)
|
|
{
|
|
TIO tio;
|
|
|
|
/* Install signal handlers */
|
|
#ifdef MODEM_WATCH_CARRIER
|
|
signal(SIGHUP, interrupt);
|
|
#else
|
|
signal(SIGHUP, linedrop);
|
|
#endif
|
|
signal(SIGINT, interrupt);
|
|
signal(SIGTERM, interrupt);
|
|
|
|
/*
|
|
* Set descriptor I/O to the non-blocking mode
|
|
*/
|
|
if( fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK) == -1 )
|
|
{
|
|
logerr("cannot set non-blocking mode for stdin");
|
|
return -1;
|
|
}
|
|
|
|
if( isatty(fd) )
|
|
{
|
|
/* Report to tty I/O routines that we are using modem */
|
|
tty_modem = 1;
|
|
|
|
if( tio_get(fd, &tio) == -1 )
|
|
{
|
|
logerr("initport error: cannot get terminal settings");
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
* Save old settings. We will restore them on exit.
|
|
*/
|
|
if( oldtio )
|
|
*oldtio = tio;
|
|
|
|
/* Set "raw" mode */
|
|
tio_set_raw_mode(&tio);
|
|
|
|
/* Set hardware flow control */
|
|
if( tio_set_flow_control(fd, &tio, FLOW_HARD) == -1 )
|
|
return -1;
|
|
|
|
/* Should we ignore DCD? */
|
|
#ifdef MODEM_WATCH_CARRIER
|
|
tio_set_local(&tio, TRUE);
|
|
#else
|
|
tio_set_local(&tio, local);
|
|
#endif
|
|
|
|
/* Set port speed */
|
|
if( portspeed )
|
|
{
|
|
/* set bit rate */
|
|
tio_set_speed(&tio, portspeed);
|
|
}
|
|
|
|
if( tio_set(fd, &tio) == -1 )
|
|
{
|
|
logerr("initport error: cannot set terminal settings");
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int port_carrier(int fd, bool online)
|
|
{
|
|
tty_online = online;
|
|
|
|
#ifndef MODEM_WATCH_CARRIER
|
|
if( isatty(fd) )
|
|
{
|
|
TIO tio;
|
|
|
|
if( tio_get(fd, &tio) == -1 )
|
|
{
|
|
logerr("port_carrier error: cannot get terminal settings");
|
|
return -1;
|
|
}
|
|
|
|
tio_set_local(&tio, online ? FALSE : TRUE);
|
|
|
|
if( tio_set(fd, &tio) == -1 )
|
|
{
|
|
logerr("port_carrier error: cannot set terminal settings");
|
|
return -1;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Restore old terminal settings
|
|
*/
|
|
int port_deinit(int fd, TIO *oldtio)
|
|
{
|
|
if( tio_set(fd, oldtio) == -1 )
|
|
{
|
|
logerr("deinitport error: cannot restore terminal settings");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Close port
|
|
*/
|
|
void port_close(void)
|
|
{
|
|
DEB((D_MODEM, "closeport: close modem port"));
|
|
/* Do nothing */
|
|
}
|
|
|