cscg24-guacamole

CSCG 2024 Challenge 'Guacamole Mashup'
git clone https://git.sinitax.com/sinitax/cscg24-guacamole
Log | Files | Refs | sfeed.txt

clipboard.c (4834B)


      1/*
      2 * Licensed to the Apache Software Foundation (ASF) under one
      3 * or more contributor license agreements.  See the NOTICE file
      4 * distributed with this work for additional information
      5 * regarding copyright ownership.  The ASF licenses this file
      6 * to you under the Apache License, Version 2.0 (the
      7 * "License"); you may not use this file except in compliance
      8 * with the License.  You may obtain a copy of the License at
      9 *
     10 *   http://www.apache.org/licenses/LICENSE-2.0
     11 *
     12 * Unless required by applicable law or agreed to in writing,
     13 * software distributed under the License is distributed on an
     14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     15 * KIND, either express or implied.  See the License for the
     16 * specific language governing permissions and limitations
     17 * under the License.
     18 */
     19
     20#include "config.h"
     21#include "common/clipboard.h"
     22
     23#include <guacamole/client.h>
     24#include <guacamole/mem.h>
     25#include <guacamole/protocol.h>
     26#include <guacamole/stream.h>
     27#include <guacamole/string.h>
     28#include <guacamole/user.h>
     29#include <pthread.h>
     30#include <string.h>
     31#include <stdlib.h>
     32
     33guac_common_clipboard* guac_common_clipboard_alloc() {
     34
     35    guac_common_clipboard* clipboard = guac_mem_alloc(sizeof(guac_common_clipboard));
     36
     37    /* Init clipboard */
     38    clipboard->mimetype[0] = '\0';
     39    clipboard->buffer = guac_mem_alloc(GUAC_COMMON_CLIPBOARD_MAX_LENGTH);
     40    clipboard->available = GUAC_COMMON_CLIPBOARD_MAX_LENGTH;
     41    clipboard->length = 0;
     42
     43    pthread_mutex_init(&(clipboard->lock), NULL);
     44
     45    return clipboard;
     46
     47}
     48
     49void guac_common_clipboard_free(guac_common_clipboard* clipboard) {
     50
     51    /* Destroy lock */
     52    pthread_mutex_destroy(&(clipboard->lock));
     53
     54    /* Free buffer */
     55    guac_mem_free(clipboard->buffer);
     56
     57    /* Free base structure */
     58    guac_mem_free(clipboard);
     59
     60}
     61
     62/**
     63 * Callback for guac_client_foreach_user() which sends clipboard data to each
     64 * connected client.
     65 *
     66 * @param user
     67 *     The user to send the clipboard data to.
     68 *
     69 * @param
     70 *     A pointer to the guac_common_clipboard structure containing the
     71 *     clipboard data that should be sent to the given user.
     72 *
     73 * @return
     74 *     Always NULL.
     75 */
     76static void* __send_user_clipboard(guac_user* user, void* data) {
     77
     78    guac_common_clipboard* clipboard = (guac_common_clipboard*) data;
     79
     80    char* current = clipboard->buffer;
     81    int remaining = clipboard->length;
     82
     83    /* Begin stream */
     84    guac_stream* stream = guac_user_alloc_stream(user);
     85    guac_protocol_send_clipboard(user->socket, stream, clipboard->mimetype);
     86
     87    guac_user_log(user, GUAC_LOG_DEBUG,
     88            "Created stream %i for %s clipboard data.",
     89            stream->index, clipboard->mimetype);
     90
     91    /* Split clipboard into chunks */
     92    while (remaining > 0) {
     93
     94        /* Calculate size of next block */
     95        int block_size = GUAC_COMMON_CLIPBOARD_BLOCK_SIZE;
     96        if (remaining < block_size)
     97            block_size = remaining; 
     98
     99        /* Send block */
    100        guac_protocol_send_blob(user->socket, stream, current, block_size);
    101        guac_user_log(user, GUAC_LOG_DEBUG,
    102                "Sent %i bytes of clipboard data on stream %i.",
    103                block_size, stream->index);
    104
    105        /* Next block */
    106        remaining -= block_size;
    107        current += block_size;
    108
    109    }
    110
    111    guac_user_log(user, GUAC_LOG_DEBUG,
    112            "Clipboard stream %i complete.",
    113            stream->index);
    114
    115    /* End stream */
    116    guac_protocol_send_end(user->socket, stream);
    117    guac_user_free_stream(user, stream);
    118
    119    return NULL;
    120
    121}
    122
    123void guac_common_clipboard_send(guac_common_clipboard* clipboard, guac_client* client) {
    124
    125    pthread_mutex_lock(&(clipboard->lock));
    126
    127    guac_client_log(client, GUAC_LOG_DEBUG, "Broadcasting clipboard to all connected users.");
    128    guac_client_foreach_user(client, __send_user_clipboard, clipboard);
    129    guac_client_log(client, GUAC_LOG_DEBUG, "Broadcast of clipboard complete.");
    130
    131    pthread_mutex_unlock(&(clipboard->lock));
    132
    133}
    134
    135void guac_common_clipboard_reset(guac_common_clipboard* clipboard,
    136        const char* mimetype) {
    137
    138    pthread_mutex_lock(&(clipboard->lock));
    139
    140    /* Clear clipboard contents */
    141    clipboard->length = 0;
    142
    143    /* Assign given mimetype */
    144    guac_strlcpy(clipboard->mimetype, mimetype, sizeof(clipboard->mimetype));
    145
    146    pthread_mutex_unlock(&(clipboard->lock));
    147
    148}
    149
    150void guac_common_clipboard_append(guac_common_clipboard* clipboard, const char* data, int length) {
    151
    152    pthread_mutex_lock(&(clipboard->lock));
    153
    154    /* Truncate data to available length */
    155    int remaining = clipboard->available - clipboard->length;
    156    if (remaining < length)
    157        length = remaining;
    158
    159    /* Append to buffer */
    160    memcpy(clipboard->buffer + clipboard->length, data, length);
    161
    162    /* Update length */
    163    clipboard->length += length;
    164
    165    pthread_mutex_unlock(&(clipboard->lock));
    166
    167}
    168