2 RCSID("$OpenBSD: cli.c,v 1.7 2001/02/04 15:32:23 stevesk Exp $");
7 static int cli_input = -1;
8 static int cli_output = -1;
9 static int cli_from_stdin = 0;
22 cli_open(int from_stdin)
24 if (cli_input >= 0 && cli_output >= 0 && cli_from_stdin == from_stdin)
28 if (!cli_from_stdin && cli_input >= 0) {
29 (void)close(cli_input);
31 cli_input = STDIN_FILENO;
32 cli_output = STDERR_FILENO;
34 cli_input = cli_output = open("/dev/tty", O_RDWR);
36 fatal("You have no controlling tty. Cannot read passphrase.");
39 cli_from_stdin = from_stdin;
41 return cli_input >= 0 && cli_output >= 0 && cli_from_stdin == from_stdin;
47 if (!cli_from_stdin && cli_input >= 0)
65 sigaddset(&nset, SIGTSTP);
66 (void) sigprocmask(SIG_BLOCK, &nset, &oset);
70 memset(&nsa, 0, sizeof(nsa));
71 nsa.sa_handler = intrcatch;
72 (void) sigaction(SIGINT, &nsa, &osa);
75 if (tcgetattr(cli_input, &otio) == 0 && (otio.c_lflag & ECHO)) {
78 ntio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
79 (void) tcsetattr(cli_input, TCSANOW, &ntio);
87 if (echo_modified != 0) {
88 tcsetattr(cli_input, TCSANOW, &otio);
92 (void) sigprocmask(SIG_SETMASK, &oset, NULL);
93 (void) sigaction(SIGINT, &osa, NULL);
96 kill(getpid(), SIGINT);
98 /* XXX tty has not neccessarily drained by now? */
106 cli_read(char* buf, int size, int echo)
115 if (read(cli_input, &ch, 1) != 1)
117 if (ch == '\n' || intr != 0)
127 (void) write(cli_output, "\n", 1);
132 cli_write(const char* buf, int size)
134 int i, len, pos, ret = 0;
137 output = xmalloc(4*size);
138 for (p = output, i = 0; i < size; i++) {
142 p = vis(p, buf[i], 0, 0);
146 for (pos = 0; pos < len; pos += ret) {
147 ret = write(cli_output, output + pos, len - pos);
158 * Presents a prompt and returns the response allocated with xmalloc().
159 * Uses /dev/tty or stdin/out depending on arg. Optionally disables echo
160 * of response depending on arg. Tries to ensure that no other userland
161 * buffer is storing the response.
164 cli_read_passphrase(const char* prompt, int from_stdin, int echo_enable)
169 if (!cli_open(from_stdin))
170 fatal("Cannot read passphrase.");
174 cli_write(prompt, strlen(prompt));
175 cli_read(buf, sizeof buf, echo_enable);
180 memset(buf, 0, sizeof(buf));
185 cli_prompt(char* prompt, int echo_enable)
187 return cli_read_passphrase(prompt, 0, echo_enable);
194 cli_write(mesg, strlen(mesg));
195 cli_write("\n", strlen("\n"));