From 119f9697d131d19333e14677238a5ebede9c594f Mon Sep 17 00:00:00 2001 From: corentin-soriano Date: Sat, 20 Apr 2024 16:54:52 +0200 Subject: [PATCH 1/3] GUACAMOLE-1586: Don't add \n in clipboard if the line isn't finished. --- src/terminal/buffer.c | 5 +++++ src/terminal/select.c | 22 ++++++++++++++++++---- src/terminal/terminal-handlers.c | 20 +++++++++++++++----- src/terminal/terminal.c | 5 +++-- src/terminal/terminal/buffer.h | 6 ++++++ 5 files changed, 47 insertions(+), 11 deletions(-) diff --git a/src/terminal/buffer.c b/src/terminal/buffer.c index 59c10209..fe93fc4b 100644 --- a/src/terminal/buffer.c +++ b/src/terminal/buffer.c @@ -48,6 +48,7 @@ guac_terminal_buffer* guac_terminal_buffer_alloc(int rows, guac_terminal_char* d /* Allocate row */ row->available = 256; row->length = 0; + row->wrapped_row = false; row->characters = guac_mem_alloc(sizeof(guac_terminal_char), row->available); /* Next row */ @@ -166,6 +167,10 @@ void guac_terminal_buffer_copy_rows(guac_terminal_buffer* buffer, /* Copy data */ memcpy(dst_row->characters, src_row->characters, sizeof(guac_terminal_char) * src_row->length); dst_row->length = src_row->length; + dst_row->wrapped_row = src_row->wrapped_row; + + /* Reset src wrapped_row */ + src_row->wrapped_row = false; /* Next current_row */ current_row += step; diff --git a/src/terminal/select.c b/src/terminal/select.c index b0baeb07..acc50f15 100644 --- a/src/terminal/select.c +++ b/src/terminal/select.c @@ -371,17 +371,31 @@ void guac_terminal_select_end(guac_terminal* terminal) { /* Otherwise, copy multiple rows */ else { - /* Store first row */ + /* Get the first selected row */ + guac_terminal_buffer_row* buffer_row = guac_terminal_buffer_get_row(terminal->buffer, start_row, 0); + + /* Store first row from start_col to last available col */ guac_terminal_clipboard_append_row(terminal, start_row, start_col, -1); /* Store all middle rows */ for (int row = start_row + 1; row < end_row; row++) { - guac_common_clipboard_append(terminal->clipboard, "\n", 1); + + /* Add a new line only if the line was not wrapped */ + if (buffer_row->wrapped_row == false) + guac_common_clipboard_append(terminal->clipboard, "\n", 1); + + /* Store middle row */ guac_terminal_clipboard_append_row(terminal, row, 0, -1); + + /* Get next buffer row */ + buffer_row = guac_terminal_buffer_get_row(terminal->buffer, row, 0); } - /* Store last row */ - guac_common_clipboard_append(terminal->clipboard, "\n", 1); + /* Add a new line only if the line was not wrapped */ + if (buffer_row->wrapped_row == false) + guac_common_clipboard_append(terminal->clipboard, "\n", 1); + + /* Store last row from col 0 to end_col */ guac_terminal_clipboard_append_row(terminal, end_row, 0, end_col); } diff --git a/src/terminal/terminal-handlers.c b/src/terminal/terminal-handlers.c index 7bec0f27..5a2d1349 100644 --- a/src/terminal/terminal-handlers.c +++ b/src/terminal/terminal-handlers.c @@ -57,8 +57,16 @@ * * @param term * The guac_terminal whose cursor should be advanced to the next row. + * + * @param force_wrap + * True if the line wrap was forced, false otherwise */ -static void guac_terminal_linefeed(guac_terminal* term) { +static void guac_terminal_linefeed(guac_terminal* term, bool force_wrap) { + + /* Assign in wrapped_row: 1 to avoid \n in clipboard or 0 to add \n */ + guac_terminal_buffer_row* buffer_row = + guac_terminal_buffer_get_row(term->buffer, term->cursor_row, 0); + buffer_row->wrapped_row = force_wrap; /* Scroll up if necessary */ if (term->cursor_row == term->scroll_end) @@ -221,7 +229,7 @@ int guac_terminal_echo(guac_terminal* term, unsigned char c) { case 0x0C: /* FF */ /* Advance to next row */ - guac_terminal_linefeed(term); + guac_terminal_linefeed(term, false); /* If automatic carriage return, fall through to CR handler */ if (!term->automatic_carriage_return) @@ -269,8 +277,10 @@ int guac_terminal_echo(guac_terminal* term, unsigned char c) { /* Wrap if necessary */ if (term->cursor_col >= term->term_width) { + + /* New line */ term->cursor_col = 0; - guac_terminal_linefeed(term); + guac_terminal_linefeed(term, true); } /* If insert mode, shift other characters right by 1 */ @@ -340,14 +350,14 @@ int guac_terminal_escape(guac_terminal* term, unsigned char c) { /* Index (IND) */ case 'D': - guac_terminal_linefeed(term); + guac_terminal_linefeed(term, false); term->char_handler = guac_terminal_echo; break; /* Next Line (NEL) */ case 'E': guac_terminal_move_cursor(term, term->cursor_row, 0); - guac_terminal_linefeed(term); + guac_terminal_linefeed(term, false); term->char_handler = guac_terminal_echo; break; diff --git a/src/terminal/terminal.c b/src/terminal/terminal.c index 192c85a1..15b9fea8 100644 --- a/src/terminal/terminal.c +++ b/src/terminal/terminal.c @@ -241,9 +241,10 @@ void guac_terminal_reset(guac_terminal* term) { /* Reset display palette */ guac_terminal_display_reset_palette(term->display); - /* Clear terminal */ + /* Clear terminal with a row length of term_width-1 + * to avoid exceed the size of the display layer */ for (row=0; rowterm_height; row++) - guac_terminal_set_columns(term, row, 0, term->term_width, &(term->default_char)); + guac_terminal_set_columns(term, row, 0, term->term_width-1, &(term->default_char)); } diff --git a/src/terminal/terminal/buffer.h b/src/terminal/terminal/buffer.h index 7c7f29c5..cebb8e88 100644 --- a/src/terminal/terminal/buffer.h +++ b/src/terminal/terminal/buffer.h @@ -51,6 +51,12 @@ typedef struct guac_terminal_buffer_row { */ int available; + /** + * True if the current row has been wrapped to avoid going off the screen. + * False otherwise. + */ + bool wrapped_row; + } guac_terminal_buffer_row; /** From 2d0539869169d2f031dee50c35fde301608b857d Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 28 Aug 2024 10:20:20 -0700 Subject: [PATCH 2/3] GUACAMOLE-1026: Correct and clean up FreeRDP presence/absence reporting by configure. Previously, the name of the library would change and there was no output for the "disabled" case. Here, the library name remains constant while version notes are included to the side, and the output of "disabled" is restored. --- configure.ac | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index b8bd299b..063e523f 100644 --- a/configure.ac +++ b/configure.ac @@ -731,7 +731,7 @@ fi # freerdp_version= -have_freerdp= +have_freerdp=disabled FREERDP_PLUGIN_DIR= AC_ARG_WITH([rdp], @@ -752,7 +752,7 @@ OLDCPPFLAGS="$CPPFLAGS" if test "x$with_rdp" != "xno" then - freerdp_version=3 + freerdp_version="(3.x)" have_freerdp=yes PKG_CHECK_MODULES([RDP], [freerdp3 freerdp-client3 winpr3], [CPPFLAGS="${RDP_CFLAGS} -Werror $CPPFLAGS"] @@ -768,7 +768,7 @@ fi if test "x$with_rdp" != "xno" -a "x${have_freerdp}" = "xno" then - freerdp_version=2 + freerdp_version="(2.x)" have_freerdp=yes PKG_CHECK_MODULES([RDP], [freerdp2 freerdp-client2 winpr2], [CPPFLAGS="${RDP_CFLAGS} -Werror $CPPFLAGS"] @@ -1494,7 +1494,7 @@ $PACKAGE_NAME version $PACKAGE_VERSION Library status: - freerdp${freerdp_version} ............ ${have_freerdp} + freerdp ............. ${have_freerdp} ${freerdp_version} pango ............... ${have_pango} libavcodec .......... ${have_libavcodec} libavformat ......... ${have_libavformat} @@ -1524,7 +1524,7 @@ $PACKAGE_NAME version $PACKAGE_VERSION guacenc .... ${build_guacenc} guaclog .... ${build_guaclog} - FreeRDP${freerdp_version} plugins: ${build_rdp_plugins} + FreeRDP plugins: ${build_rdp_plugins} Init scripts: ${build_init} Systemd units: ${build_systemd} From 5ec496fbaf4db624d84093388c07dd9c697efd09 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 28 Aug 2024 10:04:08 -0700 Subject: [PATCH 3/3] GUACAMOLE-600: Refactor guac_socket_tcp_connect() to guac_tcp_connect(), as it does not involve guac_socket. --- src/common-ssh/ssh.c | 4 ++-- src/libguac/Makefile.am | 4 ++-- src/libguac/guacamole/{socket-tcp.h => tcp.h} | 22 +++++++++++++------ src/libguac/{socket-tcp.c => tcp.c} | 7 +++--- src/libguac/wol.c | 6 ++--- src/protocols/telnet/telnet.c | 4 ++-- 6 files changed, 28 insertions(+), 19 deletions(-) rename src/libguac/guacamole/{socket-tcp.h => tcp.h} (71%) rename src/libguac/{socket-tcp.c => tcp.c} (96%) diff --git a/src/common-ssh/ssh.c b/src/common-ssh/ssh.c index edd2240c..37bd9d70 100644 --- a/src/common-ssh/ssh.c +++ b/src/common-ssh/ssh.c @@ -24,8 +24,8 @@ #include #include #include -#include #include +#include #include #ifdef LIBSSH2_USES_GCRYPT @@ -417,7 +417,7 @@ guac_common_ssh_session* guac_common_ssh_create_session(guac_client* client, int timeout, int keepalive, const char* host_key, guac_ssh_credential_handler* credential_handler) { - int fd = guac_socket_tcp_connect(hostname, port, timeout); + int fd = guac_tcp_connect(hostname, port, timeout); if (fd < 0) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Failed to open TCP connection to %s on %s.", hostname, port); diff --git a/src/libguac/Makefile.am b/src/libguac/Makefile.am index 06ced8cc..2386f9c3 100644 --- a/src/libguac/Makefile.am +++ b/src/libguac/Makefile.am @@ -70,11 +70,11 @@ libguacinc_HEADERS = \ guacamole/socket-constants.h \ guacamole/socket.h \ guacamole/socket-fntypes.h \ - guacamole/socket-tcp.h \ guacamole/socket-types.h \ guacamole/stream.h \ guacamole/stream-types.h \ guacamole/string.h \ + guacamole/tcp.h \ guacamole/timestamp.h \ guacamole/timestamp-types.h \ guacamole/unicode.h \ @@ -129,9 +129,9 @@ libguac_la_SOURCES = \ socket-broadcast.c \ socket-fd.c \ socket-nest.c \ - socket-tcp.c \ socket-tee.c \ string.c \ + tcp.c \ timestamp.c \ unicode.c \ user.c \ diff --git a/src/libguac/guacamole/socket-tcp.h b/src/libguac/guacamole/tcp.h similarity index 71% rename from src/libguac/guacamole/socket-tcp.h rename to src/libguac/guacamole/tcp.h index 4d13e20b..d24e4597 100644 --- a/src/libguac/guacamole/socket-tcp.h +++ b/src/libguac/guacamole/tcp.h @@ -17,17 +17,25 @@ * under the License. */ -#ifndef __GUAC_SOCKET_TCP_H -#define __GUAC_SOCKET_TCP_H +#ifndef GUAC_TCP_H +#define GUAC_TCP_H + +/** + * Provides convenience functions for establishing low-level TCP connections. + * + * @file tcp.h + */ #include "config.h" #include /** - * Given a hostname or IP address and port, attempt to connect to that - * system, returning an open socket if the connection succeeds, or a negative - * value if it fails. If it fails the errno variable will be set. + * Given a hostname or IP address and port, attempt to connect to that system, + * returning the file descriptor of an open socket if the connection succeeds, + * or a negative value if it fails. The returned file descriptor must + * eventually be freed with a call to close(). If this function fails, + * guac_error will be set appropriately. * * @param hostname * The hostname or IP address to which to attempt connections. @@ -42,6 +50,6 @@ * A valid socket if the connection succeeds, or a negative integer if it * fails. */ -int guac_socket_tcp_connect(const char* hostname, const char* port, const int timeout); +int guac_tcp_connect(const char* hostname, const char* port, const int timeout); -#endif // __GUAC_SOCKET_TCP_H \ No newline at end of file +#endif // GUAC_TCP_H diff --git a/src/libguac/socket-tcp.c b/src/libguac/tcp.c similarity index 96% rename from src/libguac/socket-tcp.c rename to src/libguac/tcp.c index 4464ce92..e4ae71f2 100644 --- a/src/libguac/socket-tcp.c +++ b/src/libguac/tcp.c @@ -19,7 +19,7 @@ #include "config.h" #include "guacamole/error.h" -#include "guacamole/socket.h" +#include "guacamole/tcp.h" #include #include @@ -27,8 +27,9 @@ #include #include #include +#include -int guac_socket_tcp_connect(const char* hostname, const char* port, const int timeout) { +int guac_tcp_connect(const char* hostname, const char* port, const int timeout) { int retval; @@ -117,4 +118,4 @@ int guac_socket_tcp_connect(const char* hostname, const char* port, const int ti /* Return the fd, or the error message if the socket connection failed. */ return fd; -} \ No newline at end of file +} diff --git a/src/libguac/wol.c b/src/libguac/wol.c index fbaa04d9..1671abcf 100644 --- a/src/libguac/wol.c +++ b/src/libguac/wol.c @@ -20,7 +20,7 @@ #include "config.h" #include "guacamole/error.h" -#include "guacamole/socket-tcp.h" +#include "guacamole/tcp.h" #include "guacamole/timestamp.h" #include "guacamole/wol.h" @@ -204,7 +204,7 @@ int guac_wol_wake_and_wait(const char* mac_addr, const char* broadcast_addr, const char* hostname, const char* port, const int timeout) { /* Attempt to connect, first. */ - int sockfd = guac_socket_tcp_connect(hostname, port, timeout); + int sockfd = guac_tcp_connect(hostname, port, timeout); /* If connection succeeds, no need to wake the system. */ if (sockfd > 0) { @@ -225,7 +225,7 @@ int guac_wol_wake_and_wait(const char* mac_addr, const char* broadcast_addr, /* Try to connect on the specified TCP port and hostname or IP. */ for (int i = 0; i < retries; i++) { - sockfd = guac_socket_tcp_connect(hostname, port, timeout); + sockfd = guac_tcp_connect(hostname, port, timeout); /* Connection succeeded - close socket and exit. */ if (sockfd > 0) { diff --git a/src/protocols/telnet/telnet.c b/src/protocols/telnet/telnet.c index a524e693..0ddcd9fc 100644 --- a/src/protocols/telnet/telnet.c +++ b/src/protocols/telnet/telnet.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include @@ -386,7 +386,7 @@ static telnet_t* __guac_telnet_create_session(guac_client* client) { guac_telnet_client* telnet_client = (guac_telnet_client*) client->data; guac_telnet_settings* settings = telnet_client->settings; - int fd = guac_socket_tcp_connect(settings->hostname, settings->port, settings->timeout); + int fd = guac_tcp_connect(settings->hostname, settings->port, settings->timeout); /* Open telnet session */ telnet_t* telnet = telnet_init(__telnet_options, __guac_telnet_event_handler, 0, client);