author | mickeyl <mickeyl> | 2003-08-10 15:17:24 (UTC) |
---|---|---|
committer | mickeyl <mickeyl> | 2003-08-10 15:17:24 (UTC) |
commit | 1fb2f4ef9788b51c67b9c0f89ac3c3ce85e45e8f (patch) (side-by-side diff) | |
tree | 73b54db5d3aa3e40f4159079c14c8fca90a76c1e /noncore/net/opierdesktop/tcp.cpp | |
parent | df6337abb65463b466435a526bf62108e72a60f7 (diff) | |
download | opie-1fb2f4ef9788b51c67b9c0f89ac3c3ce85e45e8f.zip opie-1fb2f4ef9788b51c67b9c0f89ac3c3ce85e45e8f.tar.gz opie-1fb2f4ef9788b51c67b9c0f89ac3c3ce85e45e8f.tar.bz2 |
initial import of qtrdesktop - not yet opiefied but working
Diffstat (limited to 'noncore/net/opierdesktop/tcp.cpp') (more/less context) (show whitespace changes)
-rw-r--r-- | noncore/net/opierdesktop/tcp.cpp | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/noncore/net/opierdesktop/tcp.cpp b/noncore/net/opierdesktop/tcp.cpp new file mode 100644 index 0000000..0a2ca3e --- a/dev/null +++ b/noncore/net/opierdesktop/tcp.cpp @@ -0,0 +1,181 @@ +/* + rdesktop: A Remote Desktop Protocol client. + Protocol services - TCP layer + Copyright (C) Matthew Chapman 1999-2002 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include <unistd.h> /* select read write close */ +#include <sys/socket.h> /* socket connect setsockopt */ +#include <sys/time.h> /* timeval */ +#include <netdb.h> /* gethostbyname */ +#include <netinet/in.h> /* sockaddr_in */ +#include <netinet/tcp.h> /* TCP_NODELAY */ +#include <arpa/inet.h> /* inet_addr */ +#include <fcntl.h> +#include <errno.h> /* errno */ +#include "rdesktop.h" + +#ifndef INADDR_NONE +#define INADDR_NONE ((unsigned long) -1) +#endif + +static int sock; +static struct stream in; +static struct stream out; +extern int tcp_port_rdp; + +/* Initialise TCP transport data packet */ +STREAM +tcp_init(unsigned int maxlen) +{ + if (maxlen > out.size) + { + out.data = (unsigned char*)xrealloc(out.data, maxlen); + out.size = maxlen; + } + + out.p = out.data; + out.end = out.data + out.size; + return &out; +} + +/* Send TCP transport data packet */ +void +tcp_send(STREAM s) +{ + int length = s->end - s->data; + int sent, total = 0; + + while (total < length) + { + sent = send(sock, s->data + total, length - total, 0); + if (sent == -1 && errno == EWOULDBLOCK) + { + usleep(1000); + } + else if (sent <= 0) + { + error("send: %s\n", strerror(errno)); + return; + } + else + total += sent; + } +} + +/* Receive a message on the TCP layer */ +STREAM +tcp_recv(unsigned int length) +{ + int rcvd = 0; + + if (length > in.size) + { + in.data = (unsigned char*)xrealloc(in.data, length); + in.size = length; + } + + in.end = in.p = in.data; + + while (length > 0) + { + if (!ui_select(sock)) + /* User quit */ + return NULL; + + rcvd = recv(sock, in.end, length, 0); + if (rcvd == -1 && errno == EWOULDBLOCK) + { + usleep(1000); + } + else if (rcvd == -1) + { + error("recv: %s\n", strerror(errno)); + return NULL; + } + else if (rcvd == 0) + return NULL; + else + { + in.end += rcvd; + length -= rcvd; + } + } + + return ∈ +} + +/* Establish a connection on the TCP layer */ +BOOL +tcp_connect(char *server) +{ + struct hostent *nslookup; + struct sockaddr_in servaddr; + int l_true = 1; + + if ((nslookup = gethostbyname(server)) != NULL) + { + memcpy(&servaddr.sin_addr, nslookup->h_addr, sizeof(servaddr.sin_addr)); + } + else if ((servaddr.sin_addr.s_addr = inet_addr(server)) == INADDR_NONE) + { + error("%s: unable to resolve host\n", server); + return False; + } + + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { + error("socket: %s\n", strerror(errno)); + return False; + } + + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(tcp_port_rdp); + + if (connect(sock, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) < 0) + { + error("connect: %s\n", strerror(errno)); + close(sock); + return False; + } + + /* set non blocking */ + { + int op; + op = fcntl(sock, F_GETFL); + op |= O_NONBLOCK; + fcntl(sock, F_SETFL, op); + } + +// fcntl(sock, O_NONBLOCK); + setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *) &l_true, sizeof(l_true)); + + in.size = 4096; + in.data = (unsigned char*)xmalloc(in.size); + + out.size = 4096; + out.data = (unsigned char*)xmalloc(out.size); + + return True; +} + +/* Disconnect on the TCP layer */ +void +tcp_disconnect(void) +{ + close(sock); +} |