202 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			202 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
#include "sysincludes.h"
 | 
						|
#include "mtools.h"
 | 
						|
 | 
						|
static FILE *tty=NULL;
 | 
						|
static int notty=0;	
 | 
						|
static int ttyfd=-1;
 | 
						|
#ifdef USE_RAWTERM
 | 
						|
int	mtools_raw_tty = 1;
 | 
						|
#else
 | 
						|
int	mtools_raw_tty = 0;
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef USE_RAWTERM
 | 
						|
# if defined TCSANOW && defined HAVE_TCSETATTR
 | 
						|
/* we have tcsetattr & tcgetattr. Good */
 | 
						|
typedef struct termios Terminal;
 | 
						|
#  define stty(a,b)        (void)tcsetattr(a,TCSANOW,b)
 | 
						|
#  define gtty(a,b)        (void)tcgetattr(a,b)
 | 
						|
#  define USE_TCIFLUSH
 | 
						|
 | 
						|
# elif defined TCSETS && defined TCGETS
 | 
						|
typedef struct termios Terminal;
 | 
						|
#  define stty(a,b) (void)ioctl(a,TCSETS,(char *)b)
 | 
						|
#  define gtty(a,b) (void)ioctl(a,TCGETS,(char *)b)
 | 
						|
#  define USE_TCIFLUSH
 | 
						|
 | 
						|
# elif defined TCSETA && defined TCGETA
 | 
						|
typedef struct termio Terminal;
 | 
						|
#  define stty(a,b) (void)ioctl(a,TCSETA,(char *)b)
 | 
						|
#  define gtty(a,b) (void)ioctl(a,TCGETA,(char *)b)
 | 
						|
#  define USE_TCIFLUSH
 | 
						|
 | 
						|
# elif defined(HAVE_SGTTY_H) && defined(TIOCSETP) && defined(TIOCGETP)
 | 
						|
typedef struct sgttyb Terminal;
 | 
						|
#  define stty(a,b) (void)ioctl(a,TIOCSETP,(char *)b)
 | 
						|
#  define gtty(a,b) (void)ioctl(a,TIOCGETP,(char *)b)
 | 
						|
#  define USE_SGTTY
 | 
						|
#  define discard_input(a) /**/
 | 
						|
 | 
						|
# else
 | 
						|
/* no way to use raw terminal */
 | 
						|
/*
 | 
						|
#  warning Cannot use raw terminal code (disabled)
 | 
						|
*/
 | 
						|
#  undef USE_RAWTERM
 | 
						|
# endif
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef USE_TCIFLUSH
 | 
						|
# if defined TCIFLUSH && defined HAVE_TCFLUSH
 | 
						|
#  define discard_input(a) tcflush(a,TCIFLUSH)
 | 
						|
# else
 | 
						|
#  define discard_input(a) /**/
 | 
						|
# endif
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef USE_RAWTERM
 | 
						|
 | 
						|
static int tty_mode = -1; /* 1 for raw, 0 for cooked, -1 for initial */
 | 
						|
static int need_tty_reset = 0;
 | 
						|
static int handlerIsSet = 0;
 | 
						|
 | 
						|
#define restore_tty(a) stty(STDIN,a)
 | 
						|
 | 
						|
 | 
						|
#define STDIN ttyfd
 | 
						|
#define FAIL (-1)
 | 
						|
#define DONE 0
 | 
						|
static Terminal in_orig;
 | 
						|
 | 
						|
/*--------------- Signal Handler routines -------------*/
 | 
						|
 | 
						|
static void tty_time_out(void)
 | 
						|
{
 | 
						|
	int exit_code;
 | 
						|
	signal(SIGALRM, SIG_IGN);
 | 
						|
	if(tty && need_tty_reset)
 | 
						|
		restore_tty (&in_orig);	
 | 
						|
#if future
 | 
						|
	if (fail_on_timeout)
 | 
						|
		exit_code=SHFAIL;
 | 
						|
	else {
 | 
						|
		if (default_choice && mode_defined) {
 | 
						|
			if (yes_no) {
 | 
						|
				if ('Y' == default_choice)
 | 
						|
					exit_code=0;
 | 
						|
				else
 | 
						|
					exit_code=1;
 | 
						|
			} else
 | 
						|
				exit_code=default_choice-minc+1;
 | 
						|
		} else
 | 
						|
			exit_code=DONE;
 | 
						|
	}
 | 
						|
#else
 | 
						|
	exit_code = DONE;
 | 
						|
#endif
 | 
						|
	exit(exit_code);
 | 
						|
}
 | 
						|
 | 
						|
static void cleanup_tty(void)
 | 
						|
{ 
 | 
						|
	if(tty && need_tty_reset) {
 | 
						|
		restore_tty (&in_orig);
 | 
						|
		setup_signal();
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
static void set_raw_tty(int mode)
 | 
						|
{
 | 
						|
	Terminal in_raw;
 | 
						|
 | 
						|
	if(mode != tty_mode && mode != -1) {
 | 
						|
		if(!handlerIsSet) {
 | 
						|
			/* Determine existing TTY settings */
 | 
						|
			gtty (STDIN, &in_orig);
 | 
						|
			need_tty_reset = 1;
 | 
						|
 | 
						|
			/* Restore original TTY settings on exit */
 | 
						|
			atexit(cleanup_tty);
 | 
						|
			handlerIsSet = 1;
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		setup_signal();
 | 
						|
		signal (SIGALRM, (SIG_CAST) tty_time_out);
 | 
						|
	
 | 
						|
		/* Change STDIN settings to raw */
 | 
						|
 | 
						|
		gtty (STDIN, &in_raw);
 | 
						|
		if(mode) {
 | 
						|
#ifdef USE_SGTTY
 | 
						|
			in_raw.sg_flags |= CBREAK;
 | 
						|
#else
 | 
						|
			in_raw.c_lflag &= ~ICANON;
 | 
						|
			in_raw.c_cc[VMIN]=1;
 | 
						|
			in_raw.c_cc[VTIME]=0;			
 | 
						|
#endif
 | 
						|
			stty (STDIN, &in_raw);
 | 
						|
		} else {
 | 
						|
#ifdef USE_SGTTY
 | 
						|
			in_raw.sg_flags &= ~CBREAK;
 | 
						|
#else
 | 
						|
			in_raw.c_lflag |= ICANON;
 | 
						|
#endif
 | 
						|
			stty (STDIN, &in_raw);
 | 
						|
		}
 | 
						|
		tty_mode = mode;
 | 
						|
		discard_input(STDIN);
 | 
						|
	}
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
FILE *opentty(int mode)
 | 
						|
{
 | 
						|
	if(notty)
 | 
						|
		return NULL;
 | 
						|
	if (tty == NULL) {
 | 
						|
		ttyfd = open("/dev/tty", O_RDONLY);
 | 
						|
		if(ttyfd >= 0) {
 | 
						|
			tty = fdopen(ttyfd, "r");
 | 
						|
		}
 | 
						|
	}
 | 
						|
	if  (tty == NULL){
 | 
						|
		if ( !isatty(0) ){
 | 
						|
			notty = 1;
 | 
						|
			return NULL;
 | 
						|
		}
 | 
						|
		ttyfd = 0;
 | 
						|
		tty = stdin;
 | 
						|
	}
 | 
						|
#ifdef USE_RAWTERM
 | 
						|
	if(mtools_raw_tty)
 | 
						|
		set_raw_tty(mode);
 | 
						|
#endif
 | 
						|
	return tty;
 | 
						|
}
 | 
						|
 | 
						|
int ask_confirmation(const char *format, const char *p1, const char *p2)
 | 
						|
{
 | 
						|
	char ans[10];
 | 
						|
 | 
						|
	if(!opentty(-1))
 | 
						|
		return 0;
 | 
						|
 | 
						|
	while (1) {
 | 
						|
		fprintf(stderr, format, p1, p2);
 | 
						|
		fflush(stderr);
 | 
						|
		fflush(opentty(-1));
 | 
						|
		if (mtools_raw_tty) {
 | 
						|
			ans[0] = fgetc(opentty(1));
 | 
						|
			fputs("\n", stderr);
 | 
						|
		} else {
 | 
						|
			fgets(ans,9, opentty(0));
 | 
						|
		}
 | 
						|
		if (ans[0] == 'y' || ans[0] == 'Y')
 | 
						|
			return 0;
 | 
						|
		if (ans[0] == 'n' || ans[0] == 'N')
 | 
						|
			return -1;
 | 
						|
	}
 | 
						|
}
 |