Michael Jumper 4282da662f GUACAMOLE-249: Restructure audio input such that audio buffer can be separately linked.
On some platforms, the libguacai-client.so plugin for FreeRDP reports an
unlinked symbol:

    undefined symbol: guac_freerdp_dynamic_channel_collection_add	(/usr/local/lib/freerdp2/libguacai-client.so)

This symbol is actually unused within the plugin, but may be referenced
due to being defined within a function in a common piece of source
shared between the plugin and the RDP support.

Separating the actual common components such that they can be included
by both the RDP support and the libguacai-client.so plugin removes the
potential for unused pieces being flagged as missing.
2020-01-12 22:04:01 -08:00

167 lines
5.1 KiB
C

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include "channels/audio-input/audio-input.h"
#include "channels/cliprdr.h"
#include "channels/pipe-svc.h"
#include "common/cursor.h"
#include "common/display.h"
#include "config.h"
#include "input.h"
#include "rdp.h"
#include "settings.h"
#include "upload.h"
#include "user.h"
#ifdef ENABLE_COMMON_SSH
#include "sftp.h"
#endif
#include <guacamole/audio.h>
#include <guacamole/client.h>
#include <guacamole/protocol.h>
#include <guacamole/socket.h>
#include <guacamole/stream.h>
#include <guacamole/user.h>
#include <pthread.h>
#include <stddef.h>
int guac_rdp_user_join_handler(guac_user* user, int argc, char** argv) {
guac_rdp_client* rdp_client = (guac_rdp_client*) user->client->data;
/* Parse provided arguments */
guac_rdp_settings* settings = guac_rdp_parse_args(user,
argc, (const char**) argv);
/* Fail if settings cannot be parsed */
if (settings == NULL) {
guac_user_log(user, GUAC_LOG_INFO,
"Badly formatted client arguments.");
return 1;
}
/* Store settings at user level */
user->data = settings;
/* Connect via RDP if owner */
if (user->owner) {
/* Store owner's settings at client level */
rdp_client->settings = settings;
/* Start client thread */
if (pthread_create(&rdp_client->client_thread, NULL,
guac_rdp_client_thread, user->client)) {
guac_user_log(user, GUAC_LOG_ERROR,
"Unable to start VNC client thread.");
return 1;
}
/* Handle inbound audio streams if audio input is enabled */
if (settings->enable_audio_input)
user->audio_handler = guac_rdp_audio_handler;
}
/* If not owner, synchronize with current state */
else {
/* Synchronize any audio stream */
if (rdp_client->audio)
guac_audio_stream_add_user(rdp_client->audio, user);
/* Bring user up to date with any registered static channels */
guac_rdp_pipe_svc_send_pipes(user);
/* Synchronize with current display */
guac_common_display_dup(rdp_client->display, user, user->socket);
guac_socket_flush(user->socket);
}
/* Only handle events if not read-only */
if (!settings->read_only) {
/* General mouse/keyboard/clipboard events */
user->mouse_handler = guac_rdp_user_mouse_handler;
user->key_handler = guac_rdp_user_key_handler;
user->clipboard_handler = guac_rdp_clipboard_handler;
/* Display size change events */
user->size_handler = guac_rdp_user_size_handler;
/* Set generic (non-filesystem) file upload handler */
user->file_handler = guac_rdp_user_file_handler;
/* Inbound arbitrary named pipes */
user->pipe_handler = guac_rdp_pipe_svc_pipe_handler;
}
return 0;
}
int guac_rdp_user_file_handler(guac_user* user, guac_stream* stream,
char* mimetype, char* filename) {
guac_rdp_client* rdp_client = (guac_rdp_client*) user->client->data;
#ifdef ENABLE_COMMON_SSH
guac_rdp_settings* settings = rdp_client->settings;
/* If SFTP is enabled, it should be used for default uploads only if RDPDR
* is not enabled or its upload directory has been set */
if (rdp_client->sftp_filesystem != NULL) {
if (!settings->drive_enabled || settings->sftp_directory != NULL)
return guac_rdp_sftp_file_handler(user, stream, mimetype, filename);
}
#endif
/* Default to using RDPDR uploads (if enabled) */
if (rdp_client->filesystem != NULL)
return guac_rdp_upload_file_handler(user, stream, mimetype, filename);
/* File transfer not enabled */
guac_protocol_send_ack(user->socket, stream, "File transfer disabled",
GUAC_PROTOCOL_STATUS_UNSUPPORTED);
guac_socket_flush(user->socket);
return 0;
}
int guac_rdp_user_leave_handler(guac_user* user) {
guac_rdp_client* rdp_client = (guac_rdp_client*) user->client->data;
/* Update shared cursor state */
guac_common_cursor_remove_user(rdp_client->display->cursor, user);
/* Free settings if not owner (owner settings will be freed with client) */
if (!user->owner) {
guac_rdp_settings* settings = (guac_rdp_settings*) user->data;
guac_rdp_settings_free(settings);
}
return 0;
}