GUACAMOLE-313: Provide reference to in-progress screen recording.

This commit is contained in:
Michael Jumper 2017-11-27 09:38:20 -08:00
parent db85163e20
commit b37e73488f
14 changed files with 99 additions and 16 deletions

View File

@ -42,6 +42,21 @@
*/
#define GUAC_COMMON_RECORDING_MAX_NAME_LENGTH 2048
/**
* An in-progress session recording, attached to a guac_client instance such
* that output Guacamole instructions may be dynamically intercepted and
* written to a file.
*/
typedef struct guac_common_recording {
/**
* The guac_socket which writes directly to the recording file, rather than
* to any particular user.
*/
guac_socket* socket;
} guac_common_recording;
/**
* Replaces the socket of the given client such that all further Guacamole
* protocol output will be copied into a file within the given path and having
@ -68,11 +83,23 @@
* exist.
*
* @return
* Zero if the recording file has been successfully created and a recording
* will be written, non-zero otherwise.
* A new guac_common_recording structure representing the in-progress
* recording if the recording file has been successfully created and a
* recording will be written, NULL otherwise.
*/
int guac_common_recording_create(guac_client* client, const char* path,
const char* name, int create_path);
guac_common_recording* guac_common_recording_create(guac_client* client,
const char* path, const char* name, int create_path);
/**
* Frees the resources associated with the given in-progress recording. Note
* that, due to the manner that recordings are attached to the guac_client, the
* underlying guac_socket is not freed. The guac_socket will be automatically
* freed when the guac_client is freed.
*
* @param recording
* The guac_common_recording to free.
*/
void guac_common_recording_free(guac_common_recording* recording);
#endif

View File

@ -133,8 +133,8 @@ static int guac_common_recording_open(const char* path,
}
int guac_common_recording_create(guac_client* client, const char* path,
const char* name, int create_path) {
guac_common_recording* guac_common_recording_create(guac_client* client,
const char* path, const char* name, int create_path) {
char filename[GUAC_COMMON_RECORDING_MAX_NAME_LENGTH];
@ -146,7 +146,7 @@ int guac_common_recording_create(guac_client* client, const char* path,
#endif
guac_client_log(client, GUAC_LOG_ERROR,
"Creation of recording failed: %s", strerror(errno));
return 1;
return NULL;
}
/* Attempt to open recording file */
@ -154,18 +154,26 @@ int guac_common_recording_create(guac_client* client, const char* path,
if (fd == -1) {
guac_client_log(client, GUAC_LOG_ERROR,
"Creation of recording failed: %s", strerror(errno));
return 1;
return NULL;
}
/* Replace client socket with wrapped socket */
client->socket = guac_socket_tee(client->socket, guac_socket_open(fd));
/* Create recording structure with reference to underlying socket */
guac_common_recording* recording = malloc(sizeof(guac_common_recording));
recording->socket = guac_socket_open(fd);
/* Replace client socket with wrapped recording socket */
client->socket = guac_socket_tee(client->socket, recording->socket);
/* Recording creation succeeded */
guac_client_log(client, GUAC_LOG_INFO,
"Recording of session will be saved to \"%s\".",
filename);
return 0;
return recording;
}
void guac_common_recording_free(guac_common_recording* recording) {
free(recording);
}

View File

@ -20,6 +20,7 @@
#include "config.h"
#include "audio_input.h"
#include "common/recording.h"
#include "client.h"
#include "rdp.h"
#include "rdp_disp.h"
@ -122,6 +123,10 @@ int guac_rdp_client_free_handler(guac_client* client) {
guac_common_ssh_uninit();
#endif
/* Clean up recording, if in progress */
if (rdp_client->recording != NULL)
guac_common_recording_free(rdp_client->recording);
/* Clean up audio stream, if allocated */
if (rdp_client->audio != NULL)
guac_audio_stream_free(rdp_client->audio);

View File

@ -668,7 +668,7 @@ static int guac_rdp_handle_connection(guac_client* client) {
/* Set up screen recording, if requested */
if (settings->recording_path != NULL) {
guac_common_recording_create(client,
rdp_client->recording = guac_common_recording_create(client,
settings->recording_path,
settings->recording_name,
settings->create_recording_path);

View File

@ -26,6 +26,7 @@
#include "common/clipboard.h"
#include "common/display.h"
#include "common/list.h"
#include "common/recording.h"
#include "common/surface.h"
#include "keyboard.h"
#include "rdp_disp.h"
@ -143,6 +144,12 @@ typedef struct guac_rdp_client {
guac_common_ssh_sftp_filesystem* sftp_filesystem;
#endif
/**
* The in-progress session recording, or NULL if no recording is in
* progress.
*/
guac_common_recording* recording;
/**
* Display size update module.
*/

View File

@ -20,6 +20,7 @@
#include "config.h"
#include "client.h"
#include "common/recording.h"
#include "common-ssh/sftp.h"
#include "ssh.h"
#include "terminal/terminal.h"
@ -88,6 +89,10 @@ int guac_ssh_client_free_handler(guac_client* client) {
guac_common_ssh_destroy_session(ssh_client->sftp_session);
}
/* Clean up recording, if in progress */
if (ssh_client->recording != NULL)
guac_common_recording_free(ssh_client->recording);
/* Free interactive SSH session */
if (ssh_client->session != NULL)
guac_common_ssh_destroy_session(ssh_client->session);

View File

@ -193,7 +193,7 @@ void* ssh_client_thread(void* data) {
/* Set up screen recording, if requested */
if (settings->recording_path != NULL) {
guac_common_recording_create(client,
ssh_client->recording = guac_common_recording_create(client,
settings->recording_path,
settings->recording_name,
settings->create_recording_path);

View File

@ -22,6 +22,7 @@
#include "config.h"
#include "common/recording.h"
#include "common-ssh/sftp.h"
#include "common-ssh/ssh.h"
#include "common-ssh/user.h"
@ -93,6 +94,12 @@ typedef struct guac_ssh_client {
*/
guac_terminal* term;
/**
* The in-progress session recording, or NULL if no recording is in
* progress.
*/
guac_common_recording* recording;
} guac_ssh_client ;
/**

View File

@ -19,6 +19,7 @@
#include "config.h"
#include "client.h"
#include "common/recording.h"
#include "settings.h"
#include "telnet.h"
#include "terminal/terminal.h"
@ -71,6 +72,10 @@ int guac_telnet_client_free_handler(guac_client* client) {
if (telnet_client->socket_fd != -1)
close(telnet_client->socket_fd);
/* Clean up recording, if in progress */
if (telnet_client->recording != NULL)
guac_common_recording_free(telnet_client->recording);
/* Kill terminal */
guac_terminal_free(telnet_client->term);

View File

@ -467,7 +467,7 @@ void* guac_telnet_client_thread(void* data) {
/* Set up screen recording, if requested */
if (settings->recording_path != NULL) {
guac_common_recording_create(client,
telnet_client->recording = guac_common_recording_create(client,
settings->recording_path,
settings->recording_name,
settings->create_recording_path);

View File

@ -21,6 +21,7 @@
#define GUAC_TELNET_H
#include "config.h"
#include "common/recording.h"
#include "settings.h"
#include "terminal/terminal.h"
@ -70,6 +71,12 @@ typedef struct guac_telnet_client {
*/
guac_terminal* term;
/**
* The in-progress session recording, or NULL if no recording is in
* progress.
*/
guac_common_recording* recording;
} guac_telnet_client;
/**

View File

@ -19,6 +19,7 @@
#include "config.h"
#include "common/recording.h"
#include "client.h"
#include "user.h"
#include "vnc.h"
@ -102,6 +103,10 @@ int guac_vnc_client_free_handler(guac_client* client) {
guac_common_ssh_uninit();
#endif
/* Clean up recording, if in progress */
if (vnc_client->recording != NULL)
guac_common_recording_free(vnc_client->recording);
/* Free clipboard */
if (vnc_client->clipboard != NULL)
guac_common_clipboard_free(vnc_client->clipboard);

View File

@ -303,7 +303,7 @@ void* guac_vnc_client_thread(void* data) {
/* Set up screen recording, if requested */
if (settings->recording_path != NULL) {
guac_common_recording_create(client,
vnc_client->recording = guac_common_recording_create(client,
settings->recording_path,
settings->recording_name,
settings->create_recording_path);

View File

@ -25,6 +25,7 @@
#include "common/clipboard.h"
#include "common/display.h"
#include "common/iconv.h"
#include "common/recording.h"
#include "common/surface.h"
#include "settings.h"
@ -110,6 +111,12 @@ typedef struct guac_vnc_client {
guac_common_ssh_sftp_filesystem* sftp_filesystem;
#endif
/**
* The in-progress session recording, or NULL if no recording is in
* progress.
*/
guac_common_recording* recording;
/**
* Clipboard encoding-specific reader.
*/