diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2016-05-19 09:24:13 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2016-05-19 09:32:14 +0200 |
commit | e6ad880b075a38dd08d69cc4f26951a68dee1c72 (patch) | |
tree | db944b9e9878baaab4463aa22710507e0f142a71 | |
parent | b11b77765f9f6479cf928fcbd43308d2b0bccef6 (diff) | |
download | gnutls-e6ad880b075a38dd08d69cc4f26951a68dee1c72.tar.gz |
gnutls-cli: allow operation with stdin input
That is once commands from stdin are given, they are not only sent to server,
but we also wait for a response prior to exiting.
Resolves #96
-rw-r--r-- | src/cli.c | 36 | ||||
-rw-r--r-- | src/socket.c | 15 | ||||
-rw-r--r-- | src/socket.h | 2 |
3 files changed, 50 insertions, 3 deletions
@@ -1,6 +1,7 @@ /* - * Copyright (C) 2000-2014 Free Software Foundation, Inc. - * Copyright (C) 2013-2014 Nikos Mavrogiannopoulos + * Copyright (C) 2000-2016 Free Software Foundation, Inc. + * Copyright (C) 2013-2016 Nikos Mavrogiannopoulos + * Copyright (C) 2015-2016 Red Hat, Inc. * * This file is part of GnuTLS. * @@ -104,6 +105,10 @@ static gnutls_psk_client_credentials_t psk_cred; static gnutls_anon_client_credentials_t anon_cred; static gnutls_certificate_credentials_t xcred; +/* The number of seconds we wait for a reply from peer prior to + * closing the connection. */ +#define TERM_TIMEOUT 8000 + /* end of global stuff */ /* prototypes */ @@ -788,7 +793,7 @@ static int check_net_or_keyboard_input(socket_st * hd) #endif tv.tv_sec = 0; - tv.tv_usec = 50 * 1000; + tv.tv_usec = 500 * 1000; if (hd->secure == 1) if (gnutls_record_check_pending(hd->session)) @@ -1049,6 +1054,26 @@ int do_inline_command_processing(char *buffer_ptr, size_t curr_bytes, } } +static void flush_socket(socket_st *hd, unsigned ms) +{ + int ret, ii; + char buffer[MAX_BUF + 1]; + + memset(buffer, 0, MAX_BUF + 1); + ret = socket_recv_timeout(hd, buffer, MAX_BUF, ms); + if (ret == 0) + return; + else if (ret > 0) { + if (verbose != 0) + printf("- Received[%d]: ", ret); + + for (ii = 0; ii < ret; ii++) { + fputc(buffer[ii], stdout); + } + fflush(stdout); + } +} + int main(int argc, char **argv) { int ret; @@ -1059,6 +1084,7 @@ int main(int argc, char **argv) ssize_t bytes, keyboard_bytes; char *keyboard_buffer_ptr; inline_cmds_st inline_cmds; + unsigned last_op_is_write = 0; #ifndef _WIN32 struct sigaction new_action; #endif @@ -1159,6 +1185,7 @@ int main(int argc, char **argv) if (inp == IN_NET) { memset(buffer, 0, MAX_BUF + 1); + last_op_is_write = 0; ret = socket_recv(&hd, buffer, MAX_BUF); if (ret == 0) { @@ -1204,6 +1231,8 @@ int main(int argc, char **argv) break; } } else { + if (last_op_is_write) + flush_socket(&hd, TERM_TIMEOUT); user_term = 1; break; } @@ -1243,6 +1272,7 @@ int main(int argc, char **argv) } } + last_op_is_write = 1; if (ranges && gnutls_record_can_use_length_hiding(hd. session)) diff --git a/src/socket.c b/src/socket.c index 4b91daf972..ff6a5f6d0e 100644 --- a/src/socket.c +++ b/src/socket.c @@ -85,6 +85,21 @@ socket_recv(const socket_st * socket, void *buffer, int buffer_size) } ssize_t +socket_recv_timeout(const socket_st * socket, void *buffer, int buffer_size, unsigned ms) +{ + int ret; + + if (socket->secure) + gnutls_record_set_timeout(socket->session, ms); + ret = socket_recv(socket, buffer, buffer_size); + + if (socket->secure) + gnutls_record_set_timeout(socket->session, 0); + + return ret; +} + +ssize_t socket_send(const socket_st * socket, const void *buffer, int buffer_size) { return socket_send_range(socket, buffer, buffer_size, NULL); diff --git a/src/socket.h b/src/socket.h index e47138cf9e..2d4f91daad 100644 --- a/src/socket.h +++ b/src/socket.h @@ -14,6 +14,8 @@ typedef struct { ssize_t socket_recv(const socket_st * socket, void *buffer, int buffer_size); +ssize_t socket_recv_timeout(const socket_st * socket, void *buffer, + int buffer_size, unsigned ms); ssize_t socket_send(const socket_st * socket, const void *buffer, int buffer_size); ssize_t socket_send_range(const socket_st * socket, const void *buffer, |