#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stropts.h>
#include <poll.h>
#include <signal.h>
#include <errno.h>
#include "ttymon.h"
#include "tmstruct.h"
#include "tmextern.h"
#define BRK 1
#define DEL 2
struct strbuf *do_peek(int, int);
static int process(int, struct strbuf *);
static int interrupt;
int
poll_data(void)
{
int j;
struct strbuf *ptr;
struct pollfd fds[1];
struct sigaction sigact;
#ifdef DEBUG
debug("in poll_data");
#endif
if (peek_ptr != NULL) {
for (j = 0; j < peek_ptr->len; j++)
peek_ptr->buf[j] &= 0x7F;
return (process(0, peek_ptr));
}
fds[0].fd = 0;
fds[0].events = POLLIN;
sigact.sa_flags = 0;
sigact.sa_handler = sigint;
(void) sigemptyset(&sigact.sa_mask);
(void) sigaddset(&sigact.sa_mask, SIGINT);
(void) sigaction(SIGINT, &sigact, NULL);
for (;;) {
interrupt = 0;
if ((j = poll(fds, 1, -1)) == -1) {
if (interrupt == BRK) {
return (BADSPEED);
}
if (interrupt == DEL) {
return (BADSPEED);
}
} else if (j > 0) {
if (fds[0].revents & POLLHUP) {
log("POLLHUP received, about to exit");
exit(1);
}
if (fds[0].revents & POLLIN) {
ptr = do_peek(fds[0].fd, 255);
if (ptr != NULL) {
return (process(fds[0].fd, ptr));
}
}
}
}
}
static int
process(
int fd,
struct strbuf *ptr)
{
unsigned i;
char junk[BUFSIZ];
for (i = 0; i < ptr->len; i++) {
if (ptr->buf[i] == '\0') {
(void) read(fd, junk, i+1);
return (BADSPEED);
} else if ((ptr->buf[i] == '\n') || (ptr->buf[i] == '\r')) {
if (i == 0) {
(void) read(fd, junk, ptr->len);
return (NONAME);
} else
return (GOODNAME);
}
}
#ifdef DEBUG
debug("in process: EOF encountered");
#endif
exit(1);
}
struct strbuf *
do_peek(int fd, int n)
{
int ret;
static struct strpeek peek;
struct strpeek *peekp;
static char buf[BUFSIZ];
#ifdef DEBUG
debug("in do_peek");
#endif
peekp = &peek;
peekp->flags = 0;
peekp->ctlbuf.maxlen = 1;
peekp->ctlbuf.buf = buf;
peekp->databuf.maxlen = n;
peekp->databuf.buf = buf;
ret = ioctl(fd, I_PEEK, &peek);
if (ret == -1) {
log("do_peek: I_PEEK failed: %s", errno);
exit(1);
}
if (ret == 0) {
return (NULL);
}
return (&(peekp->databuf));
}
void
sigint(int s __unused)
{
struct strbuf *ptr;
char junk[2];
#ifdef DEBUG
debug("in sigint");
#endif
ptr = do_peek(0, 1);
if (ptr == NULL) {
interrupt = DEL;
} else {
if (ptr->buf[0] == '\0') {
(void) read(0, junk, 1);
interrupt = BRK;
}
}
}