magidoor/MD_Getc.c
2022-06-02 12:00:01 +10:00

160 lines
3.6 KiB
C

#include <errno.h>
#include <stdio.h>
#if defined(_MSC_VER) || defined(WIN32)
#include <winsock2.h>
#else
#include <sys/socket.h>
#include <sys/select.h>
#include <unistd.h>
#endif
#include <time.h>
#include <string.h>
#include "MagiDoor.h"
#define IAC 255
extern time_t mdtimeout;
extern time_t mdtimeremaining;
char md_getc() {
char c;
do {
c = md_getche(60, 0);
} while(c == -1);
return c;
}
char md_getche(uint32_t sec, uint32_t usec) {
char c = 'x';
int ret;
int rs;
int stage = 0;
struct timeval tv;
while (1) {
fd_set rfd;
FD_ZERO(&rfd);
if (mdcontrol.socket == -1) {
FD_SET(STDIN_FILENO, &rfd);
} else {
FD_SET(mdcontrol.socket, &rfd);
}
tv.tv_sec = sec;
tv.tv_usec = usec;
if (mdcontrol.socket == -1) {
rs = select(STDIN_FILENO + 1, &rfd, NULL, NULL, &tv);
} else {
rs = select(mdcontrol.socket + 1, &rfd, NULL, NULL, &tv);
}
if (rs == 0) {
if (mdtimeout <= time(NULL)) {
md_printf("\r\nIdle timeout!\r\n");
md_exit(0);
}
if (mdtimeremaining <= time(NULL)) {
md_printf("\r\nOut of time!\r\n");
md_exit(0);
}
return -1;
} else if (rs == -1 && errno != EINTR) {
md_exit(0);
} else if (mdcontrol.socket != -1 && FD_ISSET(mdcontrol.socket, &rfd)) {
ret = recv(mdcontrol.socket, &c, 1, 0);
if (ret <= 0) {
md_exit(0);
}
if ((unsigned char)c == IAC && stage == 0) {
stage = 1;
continue;
}
if (stage == 1) {
if ((unsigned char)c == IAC) {
stage = 0;
} else if ((unsigned char)c == 250) {
stage = 3;
continue;
} else {
stage = 2;
continue;
}
}
if (stage == 2) {
stage = 0;
continue;
}
if (stage == 3) {
if ((unsigned char)c == 240) {
stage = 0;
}
continue;
}
mdtimeout = time(NULL) + 900;
return c;
} else if (mdcontrol.socket == -1 && FD_ISSET(STDIN_FILENO, &rfd)) {
ret = read(STDIN_FILENO, &c, 1);
if (ret <= 0) {
md_exit(0);
}
mdtimeout = time(NULL) + 900;
return c;
}
}
}
char md_get_answer(const char *options) {
char c;
c = md_getc();
while (strchr(options, c) == NULL) {
c = md_getc();
}
return c;
}
int md_getstring(char *ptr, int maxlen, char minchar, char maxchar) {
char c;
int len = 0;
static char lastc = 'x';
*ptr = '\0';
while (len < maxlen) {
c = md_getc();
if (c == '\n' || c == '\0') {
lastc = c;
if (lastc == '\r') {
continue;
} else {
return len;
}
}
if (c == '\r') {
lastc = c;
return len;
}
if (c == '\b' || c == 127) {
if (len > 0) {
md_printf("\b \b");
len--;
ptr[len] = '\0';
}
lastc = c;
continue;
}
if (c >= minchar && c <= maxchar) {
ptr[len++] = c;
ptr[len] = '\0';
md_putchar(c);
}
lastc = c;
}
return len;
}