/*	$OpenBSD: cli.c,v 1.11 2001/03/06 00:33:04 deraadt Exp $	*/

/*
 * Copyright (c) 2000 Markus Friedl.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "includes.h"
RCSID("$OpenBSD: cli.c,v 1.11 2001/03/06 00:33:04 deraadt Exp $");

#include "xmalloc.h"
#include "log.h"
#include "cli.h"

static int cli_input = -1;
static int cli_output = -1;
static int cli_from_stdin = 0;

sigset_t oset;
sigset_t nset;
struct sigaction nsa;
struct sigaction osa;
struct termios ntio;
struct termios otio;
int echo_modified;

volatile int intr;

static int
cli_open(int from_stdin)
{
	if (cli_input >= 0 && cli_output >= 0 && cli_from_stdin == from_stdin)
		return 1;

	if (from_stdin) {
		if (!cli_from_stdin && cli_input >= 0) {
			(void)close(cli_input);
		}
		cli_input = STDIN_FILENO;
		cli_output = STDERR_FILENO;
	} else {
		cli_input = cli_output = open(_PATH_TTY, O_RDWR);
		if (cli_input < 0)
			fatal("You have no controlling tty.  Cannot read passphrase.");
	}

	cli_from_stdin = from_stdin;

	return cli_input >= 0 && cli_output >= 0 && cli_from_stdin == from_stdin;
}

static void
cli_close(void)
{
	if (!cli_from_stdin && cli_input >= 0)
		close(cli_input);
	cli_input = -1;
	cli_output = -1;
	cli_from_stdin = 0;
	return;
}

void
intrcatch(int sig)
{
	intr = 1;
}

static void
cli_echo_disable(void)
{
	sigemptyset(&nset);
	sigaddset(&nset, SIGTSTP);
	(void) sigprocmask(SIG_BLOCK, &nset, &oset);

	intr = 0;

	memset(&nsa, 0, sizeof(nsa));
	nsa.sa_handler = intrcatch;
	(void) sigaction(SIGINT, &nsa, &osa);

	echo_modified = 0;
	if (tcgetattr(cli_input, &otio) == 0 && (otio.c_lflag & ECHO)) {
		echo_modified = 1;
		ntio = otio;
		ntio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
		(void) tcsetattr(cli_input, TCSANOW, &ntio);
	}
	return;
}

static void
cli_echo_restore(void)
{
	if (echo_modified != 0) {
		tcsetattr(cli_input, TCSANOW, &otio);
		echo_modified = 0;
	}

	(void) sigprocmask(SIG_SETMASK, &oset, NULL);
	(void) sigaction(SIGINT, &osa, NULL);

	if (intr != 0) {
		kill(getpid(), SIGINT);
		sigemptyset(&nset);
		/* XXX tty has not neccessarily drained by now? */
		sigsuspend(&nset);
		intr = 0;
	}
	return;
}

static int
cli_read(char* buf, int size, int echo)
{
	char ch = 0;
	int i = 0;
	int n;

	if (!echo)
		cli_echo_disable();

	while (ch != '\n') {
		n = read(cli_input, &ch, 1);
		if (n == -1 && (errno == EAGAIN || errno == EINTR))
			continue;
		if (n != 1)
			break;
		if (ch == '\n' || intr != 0)
			break;
		if (i < size)
			buf[i++] = ch;
	}
	buf[i] = '\0';

	if (!echo)
		cli_echo_restore();
	if (!intr && !echo)
		(void) write(cli_output, "\n", 1);
	return i;
}

static int
cli_write(const char* buf, int size)
{
	int i, len, pos, ret = 0;
	char *output, *p;

	output = xmalloc(4*size);
	for (p = output, i = 0; i < size; i++) {
		if (buf[i] == '\n' || buf[i] == '\r')
			*p++ = buf[i];
		else
			p = vis(p, buf[i], 0, 0);
	}
	len = p - output;

	for (pos = 0; pos < len; pos += ret) {
		ret = write(cli_output, output + pos, len - pos);
		if (ret == -1) {
			xfree(output);
			return -1;
		}
	}
	xfree(output);
	return 0;
}

/*
 * Presents a prompt and returns the response allocated with xmalloc().
 * Uses /dev/tty or stdin/out depending on arg.  Optionally disables echo
 * of response depending on arg.  Tries to ensure that no other userland
 * buffer is storing the response.
 */
char*
cli_read_passphrase(const char* prompt, int from_stdin, int echo_enable)
{
	char	buf[BUFSIZ];
	char*	p;

	if (!cli_open(from_stdin))
		fatal("Cannot read passphrase.");

	fflush(stdout);

	cli_write(prompt, strlen(prompt));
	cli_read(buf, sizeof buf, echo_enable);

	cli_close();

	p = xstrdup(buf);
	memset(buf, 0, sizeof(buf));
	return (p);
}

char*
cli_prompt(char* prompt, int echo_enable)
{
	return cli_read_passphrase(prompt, 0, echo_enable);
}

void
cli_mesg(char* mesg)
{
	cli_open(0);
	cli_write(mesg, strlen(mesg));
	cli_write("\n", strlen("\n"));
	cli_close();
	return;
}
