GUACAMOLE-1538: Do not use terminal internals outside of terminal code.

This commit is contained in:
James Muehlner 2022-02-22 16:06:48 -08:00
parent 589e0ecd03
commit 6dd33a8d90
18 changed files with 254 additions and 79 deletions

View File

@ -21,7 +21,6 @@
#include "argv.h"
#include "kubernetes.h"
#include "terminal/terminal.h"
#include "terminal/terminal_priv.h"
#include <guacamole/protocol.h>
#include <guacamole/socket.h>
@ -54,8 +53,9 @@ int guac_kubernetes_argv_callback(guac_user* user, const char* mimetype,
}
/* Update Kubernetes terminal size */
guac_kubernetes_resize(client, terminal->term_height,
terminal->term_width);
guac_kubernetes_resize(client,
guac_terminal_term_height(terminal),
guac_terminal_term_width(terminal));
return 0;
@ -68,20 +68,20 @@ void* guac_kubernetes_send_current_argv(guac_user* user, void* data) {
/* Send current color scheme */
guac_user_stream_argv(user, user->socket, "text/plain",
GUAC_KUBERNETES_ARGV_COLOR_SCHEME, terminal->color_scheme);
GUAC_KUBERNETES_ARGV_COLOR_SCHEME,
guac_terminal_color_scheme(terminal));
/* Send current font name */
guac_user_stream_argv(user, user->socket, "text/plain",
GUAC_KUBERNETES_ARGV_FONT_NAME, terminal->font_name);
GUAC_KUBERNETES_ARGV_FONT_NAME,
guac_terminal_font_name(terminal));
/* Send current font size */
char font_size[64];
sprintf(font_size, "%i", terminal->font_size);
sprintf(font_size, "%i", guac_terminal_font_size(terminal));
guac_user_stream_argv(user, user->socket, "text/plain",
GUAC_KUBERNETES_ARGV_FONT_SIZE, font_size);
return NULL;
}

View File

@ -18,9 +18,8 @@
*/
#include "clipboard.h"
#include "common/clipboard.h"
#include "kubernetes.h"
#include "terminal/terminal_priv.h"
#include "terminal/terminal.h"
#include <guacamole/client.h>
#include <guacamole/stream.h>
@ -34,7 +33,7 @@ int guac_kubernetes_clipboard_handler(guac_user* user, guac_stream* stream,
(guac_kubernetes_client*) client->data;
/* Clear clipboard and prepare for new data */
guac_common_clipboard_reset(kubernetes_client->term->clipboard, mimetype);
guac_terminal_clipboard_reset(kubernetes_client->term, mimetype);
/* Set handlers for clipboard stream */
stream->blob_handler = guac_kubernetes_clipboard_blob_handler;
@ -51,7 +50,7 @@ int guac_kubernetes_clipboard_blob_handler(guac_user* user,
(guac_kubernetes_client*) client->data;
/* Append new data */
guac_common_clipboard_append(kubernetes_client->term->clipboard, data, length);
guac_terminal_clipboard_append(kubernetes_client->term, data, length);
return 0;
}

View File

@ -21,7 +21,6 @@
#include "input.h"
#include "kubernetes.h"
#include "terminal/terminal.h"
#include "terminal/terminal_priv.h"
#include <guacamole/client.h>
#include <guacamole/user.h>
@ -87,8 +86,9 @@ int guac_kubernetes_user_size_handler(guac_user* user, int width, int height) {
guac_terminal_resize(terminal, width, height);
/* Update Kubernetes terminal window size if connected */
guac_kubernetes_resize(client, terminal->term_height,
terminal->term_width);
guac_kubernetes_resize(client,
guac_terminal_term_height(terminal),
guac_terminal_term_width(terminal));
return 0;
}

View File

@ -26,7 +26,6 @@
#include "kubernetes.h"
#include "ssl.h"
#include "terminal/terminal.h"
#include "terminal/terminal_priv.h"
#include "url.h"
#include <guacamole/client.h>
@ -414,8 +413,8 @@ void guac_kubernetes_force_redraw(guac_client* client) {
/* Get current terminal dimensions */
guac_terminal* term = kubernetes_client->term;
int rows = term->term_height;
int columns = term->term_width;
int rows = guac_terminal_term_height(term);
int columns = guac_terminal_term_width(term);
/* Force a redraw by increasing the terminal size by one character in
* each dimension and then resizing it back to normal (the same technique

View File

@ -25,7 +25,6 @@
#include "pipe.h"
#include "settings.h"
#include "terminal/terminal.h"
#include "terminal/terminal_priv.h"
#include "user.h"
#include <guacamole/client.h>
@ -110,8 +109,8 @@ int guac_kubernetes_user_leave_handler(guac_user* user) {
guac_kubernetes_client* kubernetes_client =
(guac_kubernetes_client*) user->client->data;
/* Update shared cursor state */
guac_common_cursor_remove_user(kubernetes_client->term->cursor, user);
/* Remove the user from the terminal */
guac_terminal_remove_user(kubernetes_client->term, user);
/* Free settings if not owner (owner settings will be freed with client) */
if (!user->owner) {

View File

@ -21,7 +21,6 @@
#include "argv.h"
#include "ssh.h"
#include "terminal/terminal.h"
#include "terminal/terminal_priv.h"
#include <guacamole/protocol.h>
#include <guacamole/socket.h>
@ -55,10 +54,12 @@ int guac_ssh_argv_callback(guac_user* user, const char* mimetype,
}
/* Update SSH pty size if connected */
int term_width = guac_terminal_term_width(terminal);
int term_height = guac_terminal_term_height(terminal);
if (ssh_client->term_channel != NULL) {
pthread_mutex_lock(&(ssh_client->term_channel_lock));
libssh2_channel_request_pty_size(ssh_client->term_channel,
terminal->term_width, terminal->term_height);
term_width, term_height);
pthread_mutex_unlock(&(ssh_client->term_channel_lock));
}
@ -73,15 +74,17 @@ void* guac_ssh_send_current_argv(guac_user* user, void* data) {
/* Send current color scheme */
guac_user_stream_argv(user, user->socket, "text/plain",
GUAC_SSH_ARGV_COLOR_SCHEME, terminal->color_scheme);
GUAC_SSH_ARGV_COLOR_SCHEME,
guac_terminal_color_scheme(terminal));
/* Send current font name */
guac_user_stream_argv(user, user->socket, "text/plain",
GUAC_SSH_ARGV_FONT_NAME, terminal->font_name);
GUAC_SSH_ARGV_FONT_NAME,
guac_terminal_font_name(terminal));
/* Send current font size */
char font_size[64];
sprintf(font_size, "%i", terminal->font_size);
sprintf(font_size, "%i", guac_terminal_font_size(terminal));
guac_user_stream_argv(user, user->socket, "text/plain",
GUAC_SSH_ARGV_FONT_SIZE, font_size);

View File

@ -19,10 +19,8 @@
#include "config.h"
#include "clipboard.h"
#include "common/clipboard.h"
#include "ssh.h"
#include "terminal/terminal.h"
#include "terminal/terminal_priv.h"
#include <guacamole/client.h>
#include <guacamole/stream.h>
@ -34,7 +32,7 @@ int guac_ssh_clipboard_handler(guac_user* user, guac_stream* stream,
/* Clear clipboard and prepare for new data */
guac_client* client = user->client;
guac_ssh_client* ssh_client = (guac_ssh_client*) client->data;
guac_common_clipboard_reset(ssh_client->term->clipboard, mimetype);
guac_terminal_clipboard_reset(ssh_client->term, mimetype);
/* Set handlers for clipboard stream */
stream->blob_handler = guac_ssh_clipboard_blob_handler;
@ -49,7 +47,7 @@ int guac_ssh_clipboard_blob_handler(guac_user* user, guac_stream* stream,
/* Append new data */
guac_client* client = user->client;
guac_ssh_client* ssh_client = (guac_ssh_client*) client->data;
guac_common_clipboard_append(ssh_client->term->clipboard, data, length);
guac_terminal_clipboard_append(ssh_client->term, data, length);
return 0;
}

View File

@ -24,7 +24,6 @@
#include "common/recording.h"
#include "ssh.h"
#include "terminal/terminal.h"
#include "terminal/terminal_priv.h"
#include <guacamole/client.h>
#include <guacamole/user.h>
@ -89,7 +88,8 @@ int guac_ssh_user_size_handler(guac_user* user, int width, int height) {
if (ssh_client->term_channel != NULL) {
pthread_mutex_lock(&(ssh_client->term_channel_lock));
libssh2_channel_request_pty_size(ssh_client->term_channel,
terminal->term_width, terminal->term_height);
guac_terminal_term_width(terminal),
guac_terminal_term_height(terminal));
pthread_mutex_unlock(&(ssh_client->term_channel_lock));
}

View File

@ -27,7 +27,6 @@
#include "sftp.h"
#include "ssh.h"
#include "terminal/terminal.h"
#include "terminal/terminal_priv.h"
#include "ttymode.h"
#ifdef ENABLE_SSH_AGENT
@ -359,10 +358,12 @@ void* ssh_client_thread(void* data) {
/* Init handlers for Guacamole-specific console codes */
if (!settings->sftp_disable_upload)
ssh_client->term->upload_path_handler = guac_sftp_set_upload_path;
guac_terminal_set_upload_path_handler(ssh_client->term,
guac_sftp_set_upload_path);
if (!settings->sftp_disable_download)
ssh_client->term->file_download_handler = guac_sftp_download_file;
guac_terminal_set_file_download_handler(ssh_client->term,
guac_sftp_download_file);
guac_client_log(client, GUAC_LOG_DEBUG, "SFTP session initialized");
@ -376,10 +377,11 @@ void* ssh_client_thread(void* data) {
" Backspace may not work as expected.");
/* Request PTY */
int term_height = guac_terminal_term_height(ssh_client->term);
int term_width = guac_terminal_term_width(ssh_client->term);
if (libssh2_channel_request_pty_ex(ssh_client->term_channel,
settings->terminal_type, strlen(settings->terminal_type),
ssh_ttymodes, ttymodeBytes, ssh_client->term->term_width,
ssh_client->term->term_height, 0, 0)) {
ssh_ttymodes, ttymodeBytes, term_width, term_height, 0, 0)) {
guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to allocate PTY.");
return NULL;
}

View File

@ -25,7 +25,7 @@
#include "input.h"
#include "user.h"
#include "pipe.h"
#include "terminal/terminal_priv.h"
#include "terminal/terminal.h"
#include "sftp.h"
#include "ssh.h"
#include "settings.h"
@ -114,8 +114,8 @@ int guac_ssh_user_leave_handler(guac_user* user) {
guac_ssh_client* ssh_client = (guac_ssh_client*) user->client->data;
/* Update shared cursor state */
guac_common_cursor_remove_user(ssh_client->term->cursor, user);
/* Remove the user from the terminal */
guac_terminal_remove_user(ssh_client->term, user);
/* Free settings if not owner (owner settings will be freed with client) */
if (!user->owner) {

View File

@ -21,7 +21,6 @@
#include "argv.h"
#include "telnet.h"
#include "terminal/terminal.h"
#include "terminal/terminal_priv.h"
#include <guacamole/protocol.h>
#include <guacamole/socket.h>
@ -55,8 +54,9 @@ int guac_telnet_argv_callback(guac_user* user, const char* mimetype,
/* Update terminal window size if connected */
if (telnet_client->telnet != NULL && telnet_client->naws_enabled)
guac_telnet_send_naws(telnet_client->telnet, terminal->term_width,
terminal->term_height);
guac_telnet_send_naws(telnet_client->telnet,
guac_terminal_term_width(terminal),
guac_terminal_term_height(terminal));
return 0;
@ -69,15 +69,17 @@ void* guac_telnet_send_current_argv(guac_user* user, void* data) {
/* Send current color scheme */
guac_user_stream_argv(user, user->socket, "text/plain",
GUAC_TELNET_ARGV_COLOR_SCHEME, terminal->color_scheme);
GUAC_TELNET_ARGV_COLOR_SCHEME,
guac_terminal_color_scheme(terminal));
/* Send current font name */
guac_user_stream_argv(user, user->socket, "text/plain",
GUAC_TELNET_ARGV_FONT_NAME, terminal->font_name);
GUAC_TELNET_ARGV_FONT_NAME,
guac_terminal_font_name(terminal));
/* Send current font size */
char font_size[64];
sprintf(font_size, "%i", terminal->font_size);
sprintf(font_size, "%i", guac_terminal_font_size(terminal));
guac_user_stream_argv(user, user->socket, "text/plain",
GUAC_TELNET_ARGV_FONT_SIZE, font_size);

View File

@ -19,10 +19,8 @@
#include "config.h"
#include "clipboard.h"
#include "common/clipboard.h"
#include "telnet.h"
#include "terminal/terminal.h"
#include "terminal/terminal_priv.h"
#include <guacamole/client.h>
#include <guacamole/stream.h>
@ -34,7 +32,7 @@ int guac_telnet_clipboard_handler(guac_user* user, guac_stream* stream,
/* Clear clipboard and prepare for new data */
guac_client* client = user->client;
guac_telnet_client* telnet_client = (guac_telnet_client*) client->data;
guac_common_clipboard_reset(telnet_client->term->clipboard, mimetype);
guac_terminal_clipboard_reset(telnet_client->term, mimetype);
/* Set handlers for clipboard stream */
stream->blob_handler = guac_telnet_clipboard_blob_handler;
@ -49,7 +47,7 @@ int guac_telnet_clipboard_blob_handler(guac_user* user, guac_stream* stream,
/* Append new data */
guac_client* client = user->client;
guac_telnet_client* telnet_client = (guac_telnet_client*) client->data;
guac_common_clipboard_append(telnet_client->term->clipboard, data, length);
guac_terminal_clipboard_append(telnet_client->term, data, length);
return 0;
}

View File

@ -21,7 +21,6 @@
#include "common/recording.h"
#include "input.h"
#include "terminal/terminal.h"
#include "terminal/terminal_priv.h"
#include "telnet.h"
#include <guacamole/client.h>
@ -101,7 +100,10 @@ int guac_telnet_user_key_handler(guac_user* user, int keysym, int pressed) {
if (pressed && (
keysym == 0xFF13 /* Pause */
|| keysym == 0xFF6B /* Break */
|| (term->mod_ctrl && keysym == '0') /* Ctrl + 0 */
|| (
guac_terminal_mod_ctrl(term)
&& keysym == '0'
) /* Ctrl + 0 */
)) {
/* Send IAC BRK */
@ -133,8 +135,9 @@ int guac_telnet_user_size_handler(guac_user* user, int width, int height) {
/* Update terminal window size if connected */
if (telnet_client->telnet != NULL && telnet_client->naws_enabled)
guac_telnet_send_naws(telnet_client->telnet, terminal->term_width,
terminal->term_height);
guac_telnet_send_naws(telnet_client->telnet,
guac_terminal_term_width(terminal),
guac_terminal_term_height(terminal));
return 0;
}

View File

@ -23,7 +23,6 @@
#include "common/recording.h"
#include "telnet.h"
#include "terminal/terminal.h"
#include "terminal/terminal_priv.h"
#include <guacamole/client.h>
#include <guacamole/protocol.h>
@ -303,7 +302,9 @@ static void __guac_telnet_event_handler(telnet_t* telnet, telnet_event_t* event,
case TELNET_EV_DO:
if (event->neg.telopt == TELNET_TELOPT_NAWS) {
telnet_client->naws_enabled = 1;
guac_telnet_send_naws(telnet, telnet_client->term->term_width, telnet_client->term->term_height);
guac_telnet_send_naws(telnet,
guac_terminal_term_width(telnet_client->term),
guac_terminal_term_height(telnet_client->term));
}
break;

View File

@ -26,7 +26,6 @@
#include "settings.h"
#include "telnet.h"
#include "terminal/terminal.h"
#include "terminal/terminal_priv.h"
#include "user.h"
#include <guacamole/client.h>
@ -109,8 +108,8 @@ int guac_telnet_user_leave_handler(guac_user* user) {
guac_telnet_client* telnet_client =
(guac_telnet_client*) user->client->data;
/* Update shared cursor state */
guac_common_cursor_remove_user(telnet_client->term->cursor, user);
/* Remove the user from the terminal */
guac_terminal_remove_user(telnet_client->term, user);
/* Free settings if not owner (owner settings will be freed with client) */
if (!user->owner) {

View File

@ -190,6 +190,14 @@ int guac_terminal_available_scroll(guac_terminal* term) {
return guac_terminal_effective_buffer_length(term) - term->term_height;
}
int guac_terminal_term_height(guac_terminal* term) {
return term->term_height;
}
int guac_terminal_term_width(guac_terminal* term) {
return term->term_width;
}
void guac_terminal_reset(guac_terminal* term) {
int row;
@ -2020,6 +2028,10 @@ void guac_terminal_apply_color_scheme(guac_terminal* terminal,
}
const char* guac_terminal_color_scheme(guac_terminal* terminal) {
return terminal->color_scheme;
}
void guac_terminal_apply_font(guac_terminal* terminal, const char* font_name,
int font_size, int dpi) {
@ -2058,3 +2070,40 @@ void guac_terminal_apply_font(guac_terminal* terminal, const char* font_name,
}
void guac_terminal_set_upload_path_handler(guac_terminal* terminal,
guac_terminal_upload_path_handler* upload_path_handler) {
terminal->upload_path_handler = upload_path_handler;
}
void guac_terminal_set_file_download_handler(guac_terminal* terminal,
guac_terminal_file_download_handler* file_download_handler) {
terminal->file_download_handler = file_download_handler;
}
const char* guac_terminal_font_name(guac_terminal* terminal) {
return terminal->font_name;
}
int guac_terminal_font_size(guac_terminal* terminal) {
return terminal->font_size;
}
int guac_terminal_mod_ctrl(guac_terminal* terminal) {
return terminal->mod_ctrl;
}
void guac_terminal_clipboard_reset(guac_terminal* terminal,
const char* mimetype) {
guac_common_clipboard_reset(terminal->clipboard, mimetype);
}
void guac_terminal_clipboard_append(guac_terminal* terminal,
const char* data, int length) {
guac_common_clipboard_append(terminal->clipboard, data, length);
}
void guac_terminal_remove_user(guac_terminal* terminal, guac_user* user) {
/* Remove the user from the terminal cursor */
guac_common_cursor_remove_user(terminal->cursor, user);
}

View File

@ -114,6 +114,10 @@
*/
#define GUAC_TERMINAL_PIPE_AUTOFLUSH 2
/**
* Represents a terminal emulator which uses a given Guacamole client to
* render itself.
*/
typedef struct guac_terminal guac_terminal;
/**
@ -281,6 +285,32 @@ guac_terminal_options* guac_terminal_options_create(guac_client* client,
*/
void guac_terminal_free(guac_terminal* term);
/**
* Set the upload path handler for the given terminal.
*
* @param terminal
* The terminal to set the upload path handler for.
*
* @param upload_path_handler
* The handler to be called whenever the necessary terminal codes are sent
* to the given terminal to change the path for future file uploads.
*/
void guac_terminal_set_upload_path_handler(guac_terminal* terminal,
guac_terminal_upload_path_handler* upload_path_handler);
/**
* Set the file download handler for the given terminal.
*
* @param terminal
* The terminal to set the file download handler for.
*
* @param upload_path_handler
* The handler to be called whenever the necessary terminal codes are sent to
* the given terminal to initiate a download of a given remote file.
*/
void guac_terminal_set_file_download_handler(guac_terminal* terminal,
guac_terminal_file_download_handler* file_download_handler);
/**
* Renders a single frame of terminal data. If data is not yet available,
* this function will block until data is written.
@ -479,6 +509,75 @@ void guac_terminal_scroll_handler(guac_terminal_scrollbar* scrollbar, int value)
void guac_terminal_dup(guac_terminal* term, guac_user* user,
guac_socket* socket);
/**
* Returns the number of rows within the buffer of the given terminal which are
* not currently displayed on screen. Adjustments to the desired scrollback
* size are taken into account, and rows which are within the buffer but
* unavailable due to being outside the desired scrollback range are ignored.
*
* @param term
* The terminal whose off-screen row count should be determined.
*
* @return
* The number of rows within the buffer which are not currently displayed
* on screen.
*/
int guac_terminal_available_scroll(guac_terminal* term);
/**
* Returns the height of the given terminal, in characters.
*
* @param term
* The terminal whose height should be determined.
*
* @return
* The height of the terminal, in characters.
*/
int guac_terminal_term_height(guac_terminal* term);
/**
* Returns the width of the given terminal, in characters.
*
* @param term
* The terminal whose width should be determined.
*
* @return
* The width of the terminal, in characters.
*/
int guac_terminal_term_width(guac_terminal* term);
/**
* Clears the clipboard contents for a given terminal, and assigns a new
* mimetype for future data.
*
* @param terminal The terminal whose clipboard is being reset.
* @param mimetype The mimetype of future data.
*/
void guac_terminal_clipboard_reset(guac_terminal* terminal,
const char* mimetype);
/**
* Appends the given data to the contents of the clipboard for the given
* terminal. The data must match the mimetype chosen for the clipboard data by
* guac_terminal_clipboard_reset().
*
* @param terminal The terminal whose clipboard is being appended to.
* @param data The data to append.
* @param length The number of bytes to append from the data given.
*/
void guac_terminal_clipboard_append(guac_terminal* terminal,
const char* data, int length);
/**
* Removes the given user from any user-specific resources internal to the
* given terminal. This function must be called whenever a user leaves a
* terminal connection.
*
* @param terminal The terminal that the given user is leaving.
* @param user The user who is disconnecting.
*/
void guac_terminal_remove_user(guac_terminal* terminal, guac_user* user);
/* INTERNAL FUNCTIONS */
@ -767,21 +866,6 @@ void guac_terminal_pipe_stream_close(guac_terminal* term);
int guac_terminal_create_typescript(guac_terminal* term, const char* path,
const char* name, int create_path);
/**
* Returns the number of rows within the buffer of the given terminal which are
* not currently displayed on screen. Adjustments to the desired scrollback
* size are taken into account, and rows which are within the buffer but
* unavailable due to being outside the desired scrollback range are ignored.
*
* @param term
* The terminal whose off-screen row count should be determined.
*
* @return
* The number of rows within the buffer which are not currently displayed
* on screen.
*/
int guac_terminal_available_scroll(guac_terminal* term);
/**
* Immediately applies the given color scheme to the given terminal, overriding
* the color scheme provided when the terminal was created. Valid color schemes
@ -796,6 +880,17 @@ int guac_terminal_available_scroll(guac_terminal* term);
void guac_terminal_apply_color_scheme(guac_terminal* terminal,
const char* color_scheme);
/**
* Returns name of the color scheme currently in use by the given terminal.
*
* @param terminal
* The terminal whose color scheme should be returned.
*
* @return
* The name of the color scheme currently in use by the given terminal.
*/
const char* guac_terminal_color_scheme(guac_terminal* terminal);
/**
* Alters the font of the terminal. The terminal will automatically be redrawn
* and resized as necessary. If the terminal size changes, the remote side of
@ -820,5 +915,37 @@ void guac_terminal_apply_color_scheme(guac_terminal* terminal,
void guac_terminal_apply_font(guac_terminal* terminal, const char* font_name,
int font_size, int dpi);
#endif
/**
* Returns the font name currently in use by the given terminal.
*
* @param terminal
* The terminal whose font name is being retrieved.
*
* @return
* The name of the font in use by the given terminal.
*/
const char* guac_terminal_font_name(guac_terminal* terminal);
/**
* Returns the font size currently in use by the given terminal.
*
* @param terminal
* The terminal whose font size is being retrieved.
*
* @return
* The size of the font in use by the given terminal.
*/
int guac_terminal_font_size(guac_terminal* terminal);
/**
* Returns the current state of the mod_ctrl flag in the given terminal.
*
* @param terminal
* The terminal for which the mod_ctrl state is being checked.
*
* @return
* The current state of the mod_ctrl flag.
*/
int guac_terminal_mod_ctrl(guac_terminal* terminal);
#endif

View File

@ -24,10 +24,6 @@
#include "common/clipboard.h"
#include "terminal/terminal.h"
/**
* Represents a terminal emulator which uses a given Guacamole client to
* render itself.
*/
struct guac_terminal {
/**