You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
hashcat/src/terminal.c

169 lines
3.0 KiB

/**
* Author......: Jens Steube <jens.steube@gmail.com>
* License.....: MIT
*/
#include "common.h"
#include "terminal.h"
#ifdef __linux__
static struct termios savemodes;
static int havemodes = 0;
int tty_break()
{
struct termios modmodes;
if (tcgetattr (fileno (stdin), &savemodes) < 0) return -1;
havemodes = 1;
modmodes = savemodes;
modmodes.c_lflag &= ~ICANON;
modmodes.c_cc[VMIN] = 1;
modmodes.c_cc[VTIME] = 0;
return tcsetattr (fileno (stdin), TCSANOW, &modmodes);
}
int tty_getchar()
{
fd_set rfds;
FD_ZERO (&rfds);
FD_SET (fileno (stdin), &rfds);
struct timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 0;
int retval = select (1, &rfds, NULL, NULL, &tv);
if (retval == 0) return 0;
if (retval == -1) return -1;
return getchar();
}
int tty_fix()
{
if (!havemodes) return 0;
return tcsetattr (fileno (stdin), TCSADRAIN, &savemodes);
}
#endif
#if defined(__APPLE__) || defined(__FreeBSD__)
static struct termios savemodes;
static int havemodes = 0;
int tty_break()
{
struct termios modmodes;
if (ioctl (fileno (stdin), TIOCGETA, &savemodes) < 0) return -1;
havemodes = 1;
modmodes = savemodes;
modmodes.c_lflag &= ~ICANON;
modmodes.c_cc[VMIN] = 1;
modmodes.c_cc[VTIME] = 0;
return ioctl (fileno (stdin), TIOCSETAW, &modmodes);
}
int tty_getchar()
{
fd_set rfds;
FD_ZERO (&rfds);
FD_SET (fileno (stdin), &rfds);
struct timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 0;
int retval = select (1, &rfds, NULL, NULL, &tv);
if (retval == 0) return 0;
if (retval == -1) return -1;
return getchar();
}
int tty_fix()
{
if (!havemodes) return 0;
return ioctl (fileno (stdin), TIOCSETAW, &savemodes);
}
#endif
#ifdef _WIN
static DWORD saveMode = 0;
int tty_break()
{
HANDLE stdinHandle = GetStdHandle (STD_INPUT_HANDLE);
GetConsoleMode (stdinHandle, &saveMode);
SetConsoleMode (stdinHandle, ENABLE_PROCESSED_INPUT);
return 0;
}
int tty_getchar()
{
HANDLE stdinHandle = GetStdHandle (STD_INPUT_HANDLE);
DWORD rc = WaitForSingleObject (stdinHandle, 1000);
if (rc == WAIT_TIMEOUT) return 0;
if (rc == WAIT_ABANDONED) return -1;
if (rc == WAIT_FAILED) return -1;
// The whole ReadConsoleInput () part is a workaround.
// For some unknown reason, maybe a mingw bug, a random signal
// is sent to stdin which unblocks WaitForSingleObject () and sets rc 0.
// Then it wants to read with getche () a keyboard input
// which has never been made.
INPUT_RECORD buf[100];
DWORD num = 0;
memset (buf, 0, sizeof (buf));
ReadConsoleInput (stdinHandle, buf, 100, &num);
FlushConsoleInputBuffer (stdinHandle);
for (DWORD i = 0; i < num; i++)
{
if (buf[i].EventType != KEY_EVENT) continue;
KEY_EVENT_RECORD KeyEvent = buf[i].Event.KeyEvent;
if (KeyEvent.bKeyDown != TRUE) continue;
return KeyEvent.uChar.AsciiChar;
}
return 0;
}
int tty_fix()
{
HANDLE stdinHandle = GetStdHandle (STD_INPUT_HANDLE);
SetConsoleMode (stdinHandle, saveMode);
return 0;
}
#endif