merge in my changes from soc-krdc branch
[kdenetwork.git] / krdc / vnc / sockets.c
blobaedf59ec7bb7553b14225f96f3de3f6583dc74aa
1 /*
2 * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
4 * This is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This software is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this software; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
17 * USA.
19 * 03-05-2002 tim@tjansen.de: removed Xt event processing for krdc
23 * sockets.c - functions to deal with sockets.
26 #include <unistd.h>
27 #include <sys/socket.h>
28 #include <errno.h>
29 #include <netinet/in.h>
30 #include <netinet/tcp.h>
31 #include <arpa/inet.h>
32 #include <netdb.h>
33 #include <fcntl.h>
34 #include <assert.h>
35 #include "vncviewer.h"
37 void PrintInHex(char *buf, int len);
39 Bool errorMessageOnReadFailure = True;
41 #define BUF_SIZE 8192
42 static char buf[BUF_SIZE];
43 static char *bufoutptr = buf;
44 static unsigned int buffered = 0;
46 /* Wait duration of select in seconds */
47 #define SELECT_PERIOD 3
51 * ReadFromRFBServer is called whenever we want to read some data from the RFB
52 * server.
54 Bool
55 ReadFromRFBServer(char *out, unsigned int n)
57 fd_set fds;
58 int e;
59 struct timeval tx;
61 if (isQuitFlagSet())
62 return False;
64 if (n <= buffered) {
65 memcpy(out, bufoutptr, n);
66 bufoutptr += n;
67 buffered -= n;
68 return True;
71 memcpy(out, bufoutptr, buffered);
73 out += buffered;
74 n -= buffered;
76 bufoutptr = buf;
77 buffered = 0;
79 if (n <= BUF_SIZE) {
81 while (buffered < n) {
82 int i;
83 if (isQuitFlagSet())
84 return False;
85 i = read(rfbsock, buf + buffered, BUF_SIZE - buffered);
87 if (i <= 0) {
88 if (i < 0) {
89 if (errno == EWOULDBLOCK || errno == EAGAIN) {
90 FD_ZERO(&fds);
91 FD_SET(rfbsock,&fds);
93 tx.tv_sec = SELECT_PERIOD;
94 tx.tv_usec = 0;
95 if ((e=select(rfbsock+1, &fds, NULL, &fds, &tx)) < 0) {
96 perror("krdc: select read");
97 return False;
99 i = 0;
100 } else {
101 perror("krdc: read");
102 return False;
104 } else {
105 fprintf(stderr,"VNC server closed connection\n");
106 return False;
109 buffered += i;
112 memcpy(out, bufoutptr, n);
113 bufoutptr += n;
114 buffered -= n;
115 return isQuitFlagSet() ? False : True;
117 } else {
119 while (n > 0) {
120 int i;
121 if (isQuitFlagSet())
122 return False;
123 i = read(rfbsock, out, n);
124 if (i <= 0) {
125 if (i < 0) {
126 if (errno == EWOULDBLOCK || errno == EAGAIN) {
127 FD_ZERO(&fds);
128 FD_SET(rfbsock,&fds);
130 tx.tv_sec = SELECT_PERIOD;
131 tx.tv_usec = 0;
132 if ((e=select(rfbsock+1, &fds, NULL, &fds, &tx)) < 0) {
133 perror("krdc: select");
134 return False;
136 i = 0;
137 } else {
138 perror("krdc: read");
139 return False;
141 } else {
142 fprintf(stderr,"VNC server closed connection\n");
143 return False;
146 out += i;
147 n -= i;
150 return isQuitFlagSet() ? False : True;
156 * Write an exact number of bytes, and don't return until you've sent them.
157 * Note: this should only be called by the WriterThread
160 Bool
161 WriteExact(int sock, const char *_buf, int n)
163 fd_set fds;
164 int i = 0;
165 int j;
166 int e;
167 struct timeval tx;
169 while (i < n) {
170 if (isQuitFlagSet())
171 return False;
172 j = write(sock, _buf + i, (n - i));
173 if (j <= 0) {
174 if (j < 0) {
175 if (errno == EWOULDBLOCK || errno == EAGAIN) {
176 FD_ZERO(&fds);
177 FD_SET(rfbsock,&fds);
179 tx.tv_sec = SELECT_PERIOD;
180 tx.tv_usec = 0;
181 if ((e=select(rfbsock+1, NULL, &fds, NULL, &tx)) < 0) {
182 perror("krdc: select write");
183 return False;
185 j = 0;
186 } else {
187 perror("krdc: write");
188 return False;
190 } else {
191 fprintf(stderr,"write failed\n");
192 return False;
195 i += j;
197 return True;
202 * ConnectToTcpAddr connects to the given TCP port.
206 ConnectToTcpAddr(unsigned int host, int port)
208 int sock;
209 struct sockaddr_in addr;
210 int one = 1;
212 addr.sin_family = AF_INET;
213 addr.sin_port = htons(port);
214 addr.sin_addr.s_addr = host;
216 sock = socket(AF_INET, SOCK_STREAM, 0);
217 if (sock < 0) {
218 perror("krdc: ConnectToTcpAddr: socket");
219 return -(int)INIT_CONNECTION_FAILED;
222 if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
223 perror("krdc: ConnectToTcpAddr: connect");
224 close(sock);
225 return -(int)INIT_NO_SERVER;
228 if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
229 (char *)&one, sizeof(one)) < 0) {
230 perror("krdc: ConnectToTcpAddr: setsockopt");
231 close(sock);
232 return -(int)INIT_CONNECTION_FAILED;
235 if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
236 perror(": AcceptTcpConnection: fcntl");
237 close(sock);
238 return -(int)INIT_CONNECTION_FAILED;
241 return sock;
246 * StringToIPAddr - convert a host string to an IP address.
249 Bool
250 StringToIPAddr(const char *str, unsigned int *addr)
252 struct hostent *hp;
254 if (strcmp(str,"") == 0) {
255 *addr = 0; /* local */
256 return True;
259 *addr = inet_addr(str);
261 if (*addr != -1)
262 return True;
264 hp = gethostbyname(str);
266 if (hp) {
267 *addr = *(unsigned int *)hp->h_addr;
268 return True;
271 return False;
276 * Print out the contents of a packet for debugging.
279 void
280 PrintInHex(char *_buf, int len)
282 int i, j;
283 char c, str[17];
285 str[16] = 0;
287 fprintf(stderr,"ReadExact: ");
289 for (i = 0; i < len; i++)
291 if ((i % 16 == 0) && (i != 0)) {
292 fprintf(stderr," ");
294 c = _buf[i];
295 str[i % 16] = (((c > 31) && (c < 127)) ? c : '.');
296 fprintf(stderr,"%02x ",(unsigned char)c);
297 if ((i % 4) == 3)
298 fprintf(stderr," ");
299 if ((i % 16) == 15)
301 fprintf(stderr,"%s\n",str);
304 if ((i % 16) != 0)
306 for (j = i % 16; j < 16; j++)
308 fprintf(stderr," ");
309 if ((j % 4) == 3) fprintf(stderr," ");
311 str[i % 16] = 0;
312 fprintf(stderr,"%s\n",str);
315 fflush(stderr);
318 void freeSocketsResources() {
319 close(rfbsock);
321 errorMessageOnReadFailure = True;
322 bufoutptr = buf;
323 buffered = 0;