#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <termio.h>
#include <sys/stermio.h>
#include <sys/termiox.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/types.h>
#include "sys/stropts.h"
#include "sys/signal.h"
#include "ttymon.h"
#include "tmstruct.h"
#include "tmextern.h"
int
set_termio(int fd, char *options, char *aspeed, int clear, long mode)
{
struct termio termio;
struct termios termios;
struct stio stermio;
struct termiox termiox;
struct winsize winsize;
struct winsize owinsize;
int term;
int cnt = 1;
char *uarg;
char *argvp[MAXARGS];
static char *binstty = "/usr/bin/stty";
static char buf[BUFSIZ];
#ifdef DEBUG
debug("in set_termio");
#endif
if ((term = get_ttymode(fd, &termio, &termios, &stermio,
&termiox, &winsize)) < 0) {
log("set_termio: get_ttymode failed: %s", strerror(errno));
return (-1);
}
owinsize = winsize;
if (clear) {
if (mode & CANON) {
termios.c_cc[VEOF] = CEOF;
termios.c_cc[VEOL] = CNUL;
} else {
termios.c_lflag &= ECHO;
termios.c_cc[VMIN] = 1;
termios.c_cc[VTIME] = 0;
}
}
if (options != NULL && *options != '\0') {
argvp[0] = binstty;
(void) strcpy(buf, options);
mkargv(buf, &argvp[1], &cnt, MAXARGS - 1);
if (aspeed != NULL && *aspeed != '\0') {
argvp[cnt++] = aspeed;
}
argvp[cnt] = (char *)0;
if ((uarg = sttyparse(cnt, argvp, term, &termio, &termios,
&termiox, &winsize)) != NULL) {
log("sttyparse unknown mode: %s", uarg);
return (-1);
}
}
if (set_ttymode(fd, term, &termio, &termios, &stermio,
&termiox, &winsize, &owinsize) != 0) {
log("set_termio: set_ttymode failed", strerror(errno));
return (-1);
}
return (0);
}
#ifdef NOT_USE
turnon_canon(int fd)
{
struct termio termio;
#ifdef DEBUG
debug("in turnon_canon");
#endif
if (ioctl(fd, TCGETA, &termio) != 0) {
log("turnon_canon: TCGETA failed, fd = %d: %s", fd,
strerror(errno));
return (-1);
}
termio.c_lflag |= (ISIG|ICANON|ECHO|ECHOE|ECHOK);
termio.c_cc[VEOF] = CEOF;
termio.c_cc[VEOL] = CNUL;
if (ioctl(fd, TCSETA, &termio) != 0) {
log("turnon_canon: TCSETA failed, fd = %d: %s", fd,
strerror(errno));
return (-1);
}
return (0);
}
#endif
void
flush_input(int fd)
{
if (ioctl(fd, I_FLUSH, FLUSHR) == -1)
log("flush_input failed, fd = %d: %s", fd, strerror(errno));
if (ioctl(fd, TCSBRK, 1) == -1)
log("drain of ouput failed, fd = %d: %s", fd, strerror(errno));
}
int
push_linedisc(
int fd,
char *modules,
char *device)
{
char *p, *tp;
char buf[BUFSIZ];
#ifdef DEBUG
debug("in push_linedisc");
#endif
p = strcpy(buf, modules);
while (ioctl(fd, I_POP, 0) >= 0)
;
for (p = strtok(p, ","); p != NULL; p = strtok(NULL, ",")) {
for (tp = p + strlen(p) - 1; tp >= p && isspace(*tp); --tp)
*tp = '\0';
if (ioctl(fd, I_PUSH, p) == -1) {
log("push (%s) on %s failed: %s", p, device,
strerror(errno));
return (-1);
}
}
return (0);
}
int
hang_up_line(int fd)
{
struct termio termio;
struct termios termios;
#ifdef DEBUG
debug("in hang_up_line");
#endif
if (ioctl(fd, TCGETS, &termios) < 0) {
if (ioctl(fd, TCGETA, &termio) < 0) {
log("hang_up_line: TCGETA failed: %s", strerror(errno));
return (-1);
}
termio.c_cflag &= ~CBAUD;
termio.c_cflag |= B0;
if (ioctl(fd, TCSETA, &termio) < 0) {
log("hang_up_line: TCSETA failed: %s", strerror(errno));
return (-1);
}
} else {
(void) cfsetospeed(&termios, B0);
if (ioctl(fd, TCSETS, &termios) < 0) {
log("hang_up_line: TCSETS failed: %s", strerror(errno));
return (-1);
}
}
return (0);
}
int
initial_termio(int fd, struct pmtab *pmptr)
{
int ret;
struct Gdef *speedef;
speedef = get_speed(pmptr);
if (speedef->g_autobaud & A_FLAG) {
pmptr->p_ttyflags |= A_FLAG;
if (auto_termio(fd) == -1) {
(void) close(fd);
return (-1);
}
} else {
if (pmptr->p_ttyflags & R_FLAG)
ret = set_termio(fd, speedef->g_iflags,
NULL, TRUE, (long)RAW);
else
ret = set_termio(fd, speedef->g_iflags,
NULL, TRUE, (long)CANON);
if (ret == -1) {
log("initial termio on (%s) failed", pmptr->p_device);
(void) close(fd);
return (-1);
}
}
return (0);
}