890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff/*
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * Copyright (C) 2000, 2001, 2004, 2007, 2016 Internet Systems Consortium, Inc. ("ISC")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff */
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff
70e5a7403f0e0a3bd292b8287c5fed5772c15270Automatic Updater/* $Id: keyboard.c,v 1.13 2007/06/19 23:47:18 tbox Exp $ */
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff#include <config.h>
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff#include <sys/param.h>
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff#include <sys/types.h>
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff#include <sys/time.h>
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff#include <sys/uio.h>
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff#include <errno.h>
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff#include <stdlib.h>
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff#include <string.h>
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff#include <termios.h>
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff#include <unistd.h>
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff#include <fcntl.h>
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff#include <isc/keyboard.h>
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff#include <isc/util.h>
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graffisc_result_t
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graffisc_keyboard_open(isc_keyboard_t *keyboard) {
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff int fd;
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff isc_result_t ret;
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff struct termios current_mode;
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff REQUIRE(keyboard != NULL);
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff fd = open("/dev/tty", O_RDONLY, 0);
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff if (fd < 0)
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff return (ISC_R_IOERROR);
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff keyboard->fd = fd;
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff if (tcgetattr(fd, &keyboard->saved_mode) < 0) {
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff ret = ISC_R_IOERROR;
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff goto errout;
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff }
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff current_mode = keyboard->saved_mode;
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff
aed3b8cb4e1e9274df734b61844845ea0e33e79bBrian Wellington current_mode.c_iflag &=
aed3b8cb4e1e9274df734b61844845ea0e33e79bBrian Wellington ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
aed3b8cb4e1e9274df734b61844845ea0e33e79bBrian Wellington current_mode.c_oflag &= ~OPOST;
aed3b8cb4e1e9274df734b61844845ea0e33e79bBrian Wellington current_mode.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
aed3b8cb4e1e9274df734b61844845ea0e33e79bBrian Wellington current_mode.c_cflag &= ~(CSIZE|PARENB);
aed3b8cb4e1e9274df734b61844845ea0e33e79bBrian Wellington current_mode.c_cflag |= CS8;
aed3b8cb4e1e9274df734b61844845ea0e33e79bBrian Wellington
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff current_mode.c_cc[VMIN] = 1;
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff current_mode.c_cc[VTIME] = 0;
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff if (tcsetattr(fd, TCSAFLUSH, &current_mode) < 0) {
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff ret = ISC_R_IOERROR;
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff goto errout;
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff }
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff
153d59973f4434d80adfa6097a31d1e349f2d3baBrian Wellington keyboard->result = ISC_R_SUCCESS;
153d59973f4434d80adfa6097a31d1e349f2d3baBrian Wellington
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff return (ISC_R_SUCCESS);
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff errout:
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff close (fd);
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff return (ret);
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff}
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graffisc_result_t
9f95b0199c3f1b0ef3d40c1854a7501d72112e5aMichael Graffisc_keyboard_close(isc_keyboard_t *keyboard, unsigned int sleeptime) {
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff REQUIRE(keyboard != NULL);
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff
153d59973f4434d80adfa6097a31d1e349f2d3baBrian Wellington if (sleeptime > 0 && keyboard->result != ISC_R_CANCELED)
9f95b0199c3f1b0ef3d40c1854a7501d72112e5aMichael Graff (void)sleep(sleeptime);
9f95b0199c3f1b0ef3d40c1854a7501d72112e5aMichael Graff
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff (void)tcsetattr(keyboard->fd, TCSAFLUSH, &keyboard->saved_mode);
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson (void)close(keyboard->fd);
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff keyboard->fd = -1;
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff return (ISC_R_SUCCESS);
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff}
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graffisc_result_t
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graffisc_keyboard_getchar(isc_keyboard_t *keyboard, unsigned char *cp) {
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff ssize_t cc;
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff unsigned char c;
153d59973f4434d80adfa6097a31d1e349f2d3baBrian Wellington cc_t *controlchars;
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff REQUIRE(keyboard != NULL);
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff REQUIRE(cp != NULL);
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff cc = read(keyboard->fd, &c, 1);
153d59973f4434d80adfa6097a31d1e349f2d3baBrian Wellington if (cc < 0) {
153d59973f4434d80adfa6097a31d1e349f2d3baBrian Wellington keyboard->result = ISC_R_IOERROR;
153d59973f4434d80adfa6097a31d1e349f2d3baBrian Wellington return (keyboard->result);
153d59973f4434d80adfa6097a31d1e349f2d3baBrian Wellington }
153d59973f4434d80adfa6097a31d1e349f2d3baBrian Wellington
153d59973f4434d80adfa6097a31d1e349f2d3baBrian Wellington controlchars = keyboard->saved_mode.c_cc;
153d59973f4434d80adfa6097a31d1e349f2d3baBrian Wellington if (c == controlchars[VINTR] || c == controlchars[VQUIT]) {
153d59973f4434d80adfa6097a31d1e349f2d3baBrian Wellington keyboard->result = ISC_R_CANCELED;
153d59973f4434d80adfa6097a31d1e349f2d3baBrian Wellington return (keyboard->result);
153d59973f4434d80adfa6097a31d1e349f2d3baBrian Wellington }
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff *cp = c;
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff return (ISC_R_SUCCESS);
890fb60939f93161ca0c63e19c7154eaf3fed156Michael Graff}
153d59973f4434d80adfa6097a31d1e349f2d3baBrian Wellington
153d59973f4434d80adfa6097a31d1e349f2d3baBrian Wellingtonisc_boolean_t
153d59973f4434d80adfa6097a31d1e349f2d3baBrian Wellingtonisc_keyboard_canceled(isc_keyboard_t *keyboard) {
e15ecf08f2068dcc73454aac814eca7bf9af174cDavid Lawrence return (ISC_TF(keyboard->result == ISC_R_CANCELED));
153d59973f4434d80adfa6097a31d1e349f2d3baBrian Wellington}