client.c (4293B)
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 "argv.h" 22#include "client.h" 23#include "settings.h" 24#include "telnet.h" 25#include "user.h" 26 27#include <langinfo.h> 28#include <locale.h> 29#include <pthread.h> 30#include <stdlib.h> 31#include <string.h> 32#include <unistd.h> 33 34#include <guacamole/argv.h> 35#include <guacamole/client.h> 36#include <guacamole/mem.h> 37#include <guacamole/recording.h> 38#include <guacamole/socket.h> 39 40/** 41 * A pending join handler implementation that will synchronize the connection 42 * state for all pending users prior to them being promoted to full user. 43 * 44 * @param client 45 * The client whose pending users are about to be promoted. 46 * 47 * @return 48 * Always zero. 49 */ 50static int guac_telnet_join_pending_handler(guac_client* client) { 51 52 guac_telnet_client* telnet_client = (guac_telnet_client*) client->data; 53 54 /* Synchronize the terminal state to all pending users */ 55 if (telnet_client->term != NULL) { 56 guac_socket* broadcast_socket = client->pending_socket; 57 guac_terminal_sync_users(telnet_client->term, client, broadcast_socket); 58 guac_telnet_send_current_argv_batch(client, broadcast_socket); 59 guac_socket_flush(broadcast_socket); 60 } 61 62 return 0; 63 64} 65 66int guac_client_init(guac_client* client) { 67 68 /* Set client args */ 69 client->args = GUAC_TELNET_CLIENT_ARGS; 70 71 /* Allocate client instance data */ 72 guac_telnet_client* telnet_client = guac_mem_zalloc(sizeof(guac_telnet_client)); 73 client->data = telnet_client; 74 75 /* Init telnet client */ 76 telnet_client->socket_fd = -1; 77 telnet_client->naws_enabled = 0; 78 telnet_client->echo_enabled = 1; 79 80 /* Set handlers */ 81 client->join_handler = guac_telnet_user_join_handler; 82 client->join_pending_handler = guac_telnet_join_pending_handler; 83 client->free_handler = guac_telnet_client_free_handler; 84 client->leave_handler = guac_telnet_user_leave_handler; 85 86 /* Register handlers for argument values that may be sent after the handshake */ 87 guac_argv_register(GUAC_TELNET_ARGV_COLOR_SCHEME, guac_telnet_argv_callback, NULL, GUAC_ARGV_OPTION_ECHO); 88 guac_argv_register(GUAC_TELNET_ARGV_FONT_NAME, guac_telnet_argv_callback, NULL, GUAC_ARGV_OPTION_ECHO); 89 guac_argv_register(GUAC_TELNET_ARGV_FONT_SIZE, guac_telnet_argv_callback, NULL, GUAC_ARGV_OPTION_ECHO); 90 91 /* Set locale and warn if not UTF-8 */ 92 setlocale(LC_CTYPE, ""); 93 if (strcmp(nl_langinfo(CODESET), "UTF-8") != 0) { 94 guac_client_log(client, GUAC_LOG_INFO, 95 "Current locale does not use UTF-8. Some characters may " 96 "not render correctly."); 97 } 98 99 /* Success */ 100 return 0; 101 102} 103 104int guac_telnet_client_free_handler(guac_client* client) { 105 106 guac_telnet_client* telnet_client = (guac_telnet_client*) client->data; 107 108 /* Close telnet connection */ 109 if (telnet_client->socket_fd != -1) 110 close(telnet_client->socket_fd); 111 112 /* Clean up recording, if in progress */ 113 if (telnet_client->recording != NULL) 114 guac_recording_free(telnet_client->recording); 115 116 /* Kill terminal */ 117 guac_terminal_free(telnet_client->term); 118 119 /* Wait for and free telnet session, if connected */ 120 if (telnet_client->telnet != NULL) { 121 pthread_join(telnet_client->client_thread, NULL); 122 telnet_free(telnet_client->telnet); 123 } 124 125 /* Free settings */ 126 if (telnet_client->settings != NULL) 127 guac_telnet_settings_free(telnet_client->settings); 128 129 guac_mem_free(telnet_client); 130 return 0; 131 132} 133