Implement prompts, do not actually redirect real STDIN/STDOUT.

This commit is contained in:
Michael Jumper 2013-05-20 00:33:17 -07:00
parent 0057460c44
commit 0f978393a6
3 changed files with 76 additions and 30 deletions

View File

@ -75,14 +75,6 @@ struct guac_terminal {
*/
pthread_mutex_t lock;
/**
* Whether input should be echoed when keys are pressed. Normally, the
* terminal on the side of the SSH server will handle this automatically,
* and this flag will need to be cleared. When SSH is not yet connected,
* this flag would need to be set for input to be visible.
*/
bool echo;
/**
* The relative offset of the display. A positive value indicates that
* many rows have been scrolled into view, zero indicates that no

View File

@ -44,46 +44,101 @@
#include "client.h"
/**
* Similar to fgets(), reads a single line from STDIN. Unlike fgets(), this
* function does not include the trailing newline character, although the
* character is removed from the input stream.
*
* @param title The title of the prompt to display.
* @param str The buffer to read the result into.
* @param size The number of bytes available in the buffer.
* @return str, or NULL if the prompt failed.
* Similar to write, but automatically retries the write operation until
* an error occurs.
*/
static char* prompt(const char* title, char* str, int size) {
static int __write_all(int fd, const char* buffer, int size) {
/* Print title */
printf("%s", title);
fflush(stdout);
int remaining = size;
while (remaining > 0) {
/* Read input */
str = fgets(str, size, stdin);
/* Attempt to write data */
int ret_val = write(fd, buffer, remaining);
if (ret_val <= 0)
return -1;
/* If successful, contine with what data remains (if any) */
remaining -= ret_val;
buffer += ret_val;
/* Remove trailing newline, if any */
if (str != NULL) {
int length = strlen(str);
if (str[length-1] == '\n')
str[length-1] = 0;
}
return size;
}
/**
* Reads a single line from STDIN.
*/
static char* prompt(guac_client* client, const char* title, char* str, int size, bool echo) {
ssh_guac_client_data* client_data = (ssh_guac_client_data*) client->data;
int pos;
char in_byte;
/* Get STDIN and STDOUT */
int stdin_fd = client_data->stdin_pipe_fd[0];
int stdout_fd = client_data->stdout_pipe_fd[1];
/* Print title */
__write_all(stdout_fd, title, strlen(title));
/* Make room for null terminator */
size--;
/* Read bytes until newline */
pos = 0;
while (pos < size && read(stdin_fd, &in_byte, 1) == 1) {
/* Backspace */
if (in_byte == 0x08) {
if (pos > 0) {
__write_all(stdout_fd, "\b \b", 3);
pos--;
}
}
/* Newline (end of input */
else if (in_byte == 0x0A) {
__write_all(stdout_fd, "\r\n", 2);
break;
}
else {
/* Store character, update buffers */
str[pos++] = in_byte;
/* Print character if echoing */
if (echo)
__write_all(stdout_fd, &in_byte, 1);
else
__write_all(stdout_fd, "*", 1);
}
}
str[pos] = 0;
return str;
}
void* ssh_client_thread(void* data) {
guac_client* client = (guac_client*) data;
char username[1024];
char password[1024];
/* Get username */
if (prompt("Login as: ", username, sizeof(username)) == NULL)
if (prompt(client, "Login as: ", username, sizeof(username), true) == NULL)
return NULL;
/* Get password */
if (prompt("Password: ", password, sizeof(password)) == NULL)
if (prompt(client, "Password: ", password, sizeof(password), false) == NULL)
return NULL;
guac_client_log_info((guac_client*) data, "got: %s ... %s", username, password);

View File

@ -94,7 +94,6 @@ guac_terminal* guac_terminal_create(guac_client* client,
term->scroll_end = term->term_height - 1;
term->text_selected = false;
term->echo = true;
/* Size display */
guac_terminal_display_resize(term->display,