int guac_client_end_frame(guac_client* client) { /* Update and send timestamp */ client->last_sent_timestamp = guac_timestamp_current(); return guac_protocol_send_sync(client->socket, client->last_sent_timestamp); }
void* __guacd_client_output_thread(void* data) { guac_client* client = (guac_client*) data; guac_socket* socket = client->socket; /* Guacamole client output loop */ while (client->state == GUAC_CLIENT_RUNNING) { /* Handle server messages */ if (client->handle_messages) { /* Only handle messages if synced within threshold */ if (client->last_sent_timestamp - client->last_received_timestamp < GUACD_SYNC_THRESHOLD) { int retval = client->handle_messages(client); if (retval) { guacd_client_log_guac_error(client, "Error handling server messages"); guac_client_stop(client); return NULL; } /* Send sync instruction */ client->last_sent_timestamp = guac_timestamp_current(); if (guac_protocol_send_sync(socket, client->last_sent_timestamp)) { guacd_client_log_guac_error(client, "Error sending \"sync\" instruction"); guac_client_stop(client); return NULL; } /* Flush */ if (guac_socket_flush(socket)) { guacd_client_log_guac_error(client, "Error flushing output"); guac_client_stop(client); return NULL; } } /* Do not spin while waiting for old sync */ else __guacdd_sleep(GUACD_MESSAGE_HANDLE_FREQUENCY); } /* If no message handler, just sleep until next sync ping */ else __guacdd_sleep(GUACD_SYNC_FREQUENCY); } /* End of output loop */ guac_client_stop(client); return NULL; }
int ssh_guac_client_size_handler(guac_client* client, int width, int height) { /* Get terminal */ ssh_guac_client_data* guac_client_data = (ssh_guac_client_data*) client->data; guac_terminal* terminal = guac_client_data->term; /* Calculate dimensions */ int rows = height / terminal->display->char_height; int columns = width / terminal->display->char_width; pthread_mutex_lock(&(terminal->lock)); /* If size has changed */ if (columns != terminal->term_width || rows != terminal->term_height) { /* Resize terminal */ guac_terminal_resize(terminal, columns, rows); /* Update cursor */ guac_terminal_commit_cursor(terminal); /* Update SSH pty size if connected */ if (guac_client_data->term_channel != NULL) libssh2_channel_request_pty_size(guac_client_data->term_channel, terminal->term_width, terminal->term_height); /* Reset scroll region */ terminal->scroll_end = rows - 1; guac_terminal_display_flush(terminal->display); guac_protocol_send_sync(terminal->client->socket, client->last_sent_timestamp); guac_socket_flush(terminal->client->socket); } pthread_mutex_unlock(&(terminal->lock)); return 0; }
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); } }