/**
 * Callback for guac_client_foreach_user() which sends clipboard data to each
 * connected client.
 *
 * @param user
 *     The user to send the clipboard data to.
 *
 * @param
 *     A pointer to the guac_common_clipboard structure containing the
 *     clipboard data that should be sent to the given user.
 *
 * @return
 *     Always NULL.
 */
static void* __send_user_clipboard(guac_user* user, void* data) {

    guac_common_clipboard* clipboard = (guac_common_clipboard*) data;

    char* current = clipboard->buffer;
    int remaining = clipboard->length;

    /* Begin stream */
    guac_stream* stream = guac_user_alloc_stream(user);
    guac_protocol_send_clipboard(user->socket, stream, clipboard->mimetype);

    guac_user_log(user, GUAC_LOG_DEBUG,
            "Created stream %i for %s clipboard data.",
            stream->index, clipboard->mimetype);

    /* Split clipboard into chunks */
    while (remaining > 0) {

        /* Calculate size of next block */
        int block_size = GUAC_COMMON_CLIPBOARD_BLOCK_SIZE;
        if (remaining < block_size)
            block_size = remaining; 

        /* Send block */
        guac_protocol_send_blob(user->socket, stream, current, block_size);
        guac_user_log(user, GUAC_LOG_DEBUG,
                "Sent %i bytes of clipboard data on stream %i.",
                block_size, stream->index);

        /* Next block */
        remaining -= block_size;
        current += block_size;

    }

    guac_user_log(user, GUAC_LOG_DEBUG,
            "Clipboard stream %i complete.",
            stream->index);

    /* End stream */
    guac_protocol_send_end(user->socket, stream);
    guac_user_free_stream(user, stream);

    return NULL;

}
Example #2
0
void guac_rdp_process_cb_data_response(guac_client* client,
        RDP_CB_DATA_RESPONSE_EVENT* event) {

    /* Received clipboard data */
    if (event->data[event->size - 1] == '\0') {

        /* Free existing data */
        free(((rdp_guac_client_data*) client->data)->clipboard);

        /* Store clipboard data */
        ((rdp_guac_client_data*) client->data)->clipboard =
            strdup((char*) event->data);

        /* Send clipboard data */
        guac_protocol_send_clipboard(client->socket, (char*) event->data);

    }
    else
        guac_client_log_error(client,
                "Clipboard data missing null terminator");

}
void test_instruction_write() {

    int rfd, wfd;
    int fd[2], childpid;

    /* Create pipe */
    CU_ASSERT_EQUAL_FATAL(pipe(fd), 0);

    /* File descriptors */
    rfd = fd[0];
    wfd = fd[1];

    /* Fork */
    if ((childpid = fork()) == -1) {
        /* ERROR */
        perror("fork");
        return;
    }

    /* Child (pipe writer) */
    if (childpid != 0) {

        guac_socket* socket;

        close(rfd);

        /* Open guac socket */
        socket = guac_socket_open(wfd);

        /* Write instruction */
        guac_protocol_send_clipboard(socket, "a" UTF8_4 "b" UTF8_4 "c");
        guac_protocol_send_sync(socket, 12345);
        guac_socket_flush(socket);

        guac_socket_close(socket);
        exit(0);
    }

    /* Parent (unit test) */
    else {

        char expected[] =
            "9.clipboard,11.a" UTF8_4 "b" UTF8_4 "c;"
            "4.sync,5.12345;";

        int numread;
        char buffer[1024];
        int offset = 0;

        close(wfd);

        /* Read everything available into buffer */
        while ((numread =
                    read(rfd,
                        &(buffer[offset]),
                        sizeof(buffer)-offset)) != 0) {
            offset += numread;
        }

        /* Add NULL terminator */
        buffer[offset] = '\0';

        /* Read value should be equal to expected value */
        CU_ASSERT_STRING_EQUAL(buffer, expected);

    }
 
}