00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <unistd.h>
00022 #include <sys/socket.h>
00023 #include <sys/time.h>
00024 #include <netdb.h>
00025 #include <netinet/in.h>
00026 #include <netinet/tcp.h>
00027 #include <arpa/inet.h>
00028 #include <fcntl.h>
00029 #include <errno.h>
00030 #include "rdesktop.h"
00031
00032 #ifndef INADDR_NONE
00033 #define INADDR_NONE ((unsigned long) -1)
00034 #endif
00035
00036 static int sock;
00037 static struct stream in;
00038 static struct stream out;
00039 extern int tcp_port_rdp;
00040
00041
00042 STREAM
00043 tcp_init(unsigned int maxlen)
00044 {
00045 if (maxlen > out.size)
00046 {
00047 out.data = (unsigned char*)xrealloc(out.data, maxlen);
00048 out.size = maxlen;
00049 }
00050
00051 out.p = out.data;
00052 out.end = out.data + out.size;
00053 return &out;
00054 }
00055
00056
00057 void
00058 tcp_send(STREAM s)
00059 {
00060 int length = s->end - s->data;
00061 int sent, total = 0;
00062
00063 while (total < length)
00064 {
00065 sent = send(sock, s->data + total, length - total, 0);
00066 if (sent == -1 && errno == EWOULDBLOCK)
00067 {
00068 usleep(1000);
00069 }
00070 else if (sent <= 0)
00071 {
00072 error("send: %s\n", strerror(errno));
00073 return;
00074 }
00075 else
00076 total += sent;
00077 }
00078 }
00079
00080
00081 STREAM
00082 tcp_recv(unsigned int length)
00083 {
00084 int rcvd = 0;
00085
00086 if (length > in.size)
00087 {
00088 in.data = (unsigned char*)xrealloc(in.data, length);
00089 in.size = length;
00090 }
00091
00092 in.end = in.p = in.data;
00093
00094 while (length > 0)
00095 {
00096 if (!ui_select(sock))
00097
00098 return NULL;
00099
00100 rcvd = recv(sock, in.end, length, 0);
00101 if (rcvd == -1 && errno == EWOULDBLOCK)
00102 {
00103 usleep(1000);
00104 }
00105 else if (rcvd == -1)
00106 {
00107 error("recv: %s\n", strerror(errno));
00108 return NULL;
00109 }
00110 else if (rcvd == 0)
00111 return NULL;
00112 else
00113 {
00114 in.end += rcvd;
00115 length -= rcvd;
00116 }
00117 }
00118
00119 return ∈
00120 }
00121
00122
00123 BOOL
00124 tcp_connect(char *server)
00125 {
00126 struct hostent *nslookup;
00127 struct sockaddr_in servaddr;
00128 int l_true = 1;
00129
00130 if ((nslookup = gethostbyname(server)) != NULL)
00131 {
00132 memcpy(&servaddr.sin_addr, nslookup->h_addr, sizeof(servaddr.sin_addr));
00133 }
00134 else if ((servaddr.sin_addr.s_addr = inet_addr(server)) == INADDR_NONE)
00135 {
00136 error("%s: unable to resolve host\n", server);
00137 return False;
00138 }
00139
00140 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
00141 {
00142 error("socket: %s\n", strerror(errno));
00143 return False;
00144 }
00145
00146 servaddr.sin_family = AF_INET;
00147 servaddr.sin_port = htons(tcp_port_rdp);
00148
00149 if (connect(sock, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) < 0)
00150 {
00151 error("connect: %s\n", strerror(errno));
00152 close(sock);
00153 return False;
00154 }
00155
00156
00157 {
00158 int op;
00159 op = fcntl(sock, F_GETFL);
00160 op |= O_NONBLOCK;
00161 fcntl(sock, F_SETFL, op);
00162 }
00163
00164
00165 setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *) &l_true, sizeof(l_true));
00166
00167 in.size = 4096;
00168 in.data = (unsigned char*)xmalloc(in.size);
00169
00170 out.size = 4096;
00171 out.data = (unsigned char*)xmalloc(out.size);
00172
00173 return True;
00174 }
00175
00176
00177 void
00178 tcp_disconnect(void)
00179 {
00180 close(sock);
00181 }