150 lines
3.5 KiB
C
150 lines
3.5 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 = '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 = 60;
|
|
tv.tv_usec = 0;
|
|
|
|
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);
|
|
}
|
|
} 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;
|
|
}
|