diff --git a/configure.ac b/configure.ac index 5caa6de77..1b57f4c5e 100644 --- a/configure.ac +++ b/configure.ac @@ -735,7 +735,7 @@ fi # freerdp_version= -have_freerdp= +have_freerdp=disabled FREERDP_PLUGIN_DIR= AC_ARG_WITH([rdp], @@ -756,7 +756,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"] @@ -772,7 +772,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"] @@ -1498,7 +1498,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} @@ -1528,7 +1528,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} diff --git a/src/common-ssh/ssh.c b/src/common-ssh/ssh.c index edd2240cf..37bd9d702 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 06ced8cc3..2386f9c31 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 4d13e20bf..d24e45971 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 4464ce925..e4ae71f24 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 fbaa04d90..1671abcfc 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 a524e6933..0ddcd9fc8 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); diff --git a/src/terminal/buffer.c b/src/terminal/buffer.c index 59c10209b..fe93fc4b6 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 08696dd41..20bf9b5d2 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 b1464ee15..a3756abae 100644 --- a/src/terminal/terminal-handlers.c +++ b/src/terminal/terminal-handlers.c @@ -62,8 +62,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) @@ -226,7 +234,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) @@ -274,8 +282,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 */ @@ -345,14 +355,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 fcc83efd0..ca63f85dd 100644 --- a/src/terminal/terminal.c +++ b/src/terminal/terminal.c @@ -242,9 +242,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 7c7f29c5c..cebb8e88e 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; /**