FreeWRL/FreeX3D  3.0.0
EAIServ.c
1 /*
2 
3 
4 Implement Socket server functionality for FreeWRL.
5 This is currently (Jun 2012) used by the EAI and the MIDI routines
6 
7 */
8 
9 /****************************************************************************
10  This file is part of the FreeWRL/FreeX3D Distribution.
11 
12  Copyright 2009 CRC Canada. (http://www.crc.gc.ca)
13 
14  FreeWRL/FreeX3D is free software: you can redistribute it and/or modify
15  it under the terms of the GNU Lesser Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  FreeWRL/FreeX3D is distributed in the hope that it will be useful,
20  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  GNU General Public License for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with FreeWRL/FreeX3D. If not, see <http://www.gnu.org/licenses/>.
26 ****************************************************************************/
27 
28 #include <config.h>
29 #if !defined(EXCLUDE_EAI)
30  #if defined(_ANDROID)
31  #include <sys/socket.h>
32  #include <asm-generic/fcntl.h>
33  #endif
34 #include <system.h>
35 #include <system_net.h>
36 
37 /*JAS - get this compiling on osx 10.4 ppc ==> system_net.h */
38 
39 /* #include <display.h> */
40 #include <internal.h>
41 #include <libFreeWRL.h>
42 
43 /* !! This stuff is private. You should only use the functions defined in libFreeWRL.h
44  * or the constants defined in SCKHeaders.h
45  */
46 
47 #include "SCKHeaders.h"
48 
49 /************************************************************************/
50 /* */
51 /* Design notes: */
52 /* FreeWRL is a server, the Java (or whatever) program is a client */
53 /* */
54 /* Commands come in, and get answered to, except for sendEvents; */
55 /* for these there is no response (makes system faster) */
56 /* */
57 /* Nodes that are registered for listening to, send async */
58 /* messages. */
59 /* */
60 /************************************************************************/
61 
62 /* static pthread_mutex_t sckbufferlock = PTHREAD_MUTEX_INITIALIZER; */
63 
64 /* State */
65 int service_connected[MAX_SERVICE_CHANNELS] ;
66 int service_failed[MAX_SERVICE_CHANNELS] ;
67 int service_onclose[MAX_SERVICE_CHANNELS] ;
68 int service_wanted[MAX_SERVICE_CHANNELS] ;
69 int service_verbose[MAX_SERVICE_CHANNELS] ;
70 int service_status[MAX_SERVICE_CHANNELS] ;
71 /* More defined in fwlio_RxTx_control as static ints */
72 
73 unsigned char loopFlags = 0;
74 
75 enum theLoopFlags {
76  NO_CLIENT_CONNECTED = 0x1,
77  NO_EAI_CLASS = 0x2,
78  NO_RETVAL_CHANGE = 0x4
79 };
80 
81 /* socket stuff */
82 struct sockaddr_in servaddr, cliaddr;
83 #define MAINSOCK_FD 0
84 #define CLIENT_FD 1
85 int SCK_descriptors[MAX_SERVICE_CHANNELS][2] ;
86 int SCK_port[MAX_SERVICE_CHANNELS] ;
87 
88 /* Buffer IO */
89 char *sock_buffers[MAX_SERVICE_CHANNELS] ;
90 int sock_bufcount[MAX_SERVICE_CHANNELS] ;
91 int sock_bufsize[MAX_SERVICE_CHANNELS] ;
92 fd_set rfds2;
93 struct timeval tv2;
94 
95 /* Low level private functions */
96 int privSocketSetup(int channel, int *sockfd, int *listenfd);
97 char *privSocketRead(int channel, char *bf, int *bfct, int *bfsz, int *listenfd);
98 
99 /* **************************************************************
100  * Public top level interface
101  * ************************************************************** */
102 
103 int fwlio_RxTx_control(int channel, int action) {
104  static int first_time = 1 ;
105  static int service_status[MAX_SERVICE_CHANNELS] ;
106  static int service_justSink[MAX_SERVICE_CHANNELS] ;
107 
108  if (service_verbose[channel] > 1) {
109  printf ("fwlio_RxTx_control(%d,...) START: called with action code %d\n", channel,action);
110  printf ("fwlio_RxTx_control: service_status[i] = %d\n", service_status[channel]) ;
111  printf ("fwlio_RxTx_control: service_justSink[i] = %d\n", service_justSink[channel]) ;
112  printf ("fwlio_RxTx_control: service_wanted[i] = %d\n", service_wanted[channel]) ;
113  printf ("fwlio_RxTx_control: service_connected[i] = %d\n", service_connected[channel]) ;
114  printf ("fwlio_RxTx_control: service_failed[i] = %d\n", service_failed[channel]) ;
115  printf ("fwlio_RxTx_control: service_onclose[i] = %d\n", service_onclose[channel]) ;
116  printf ("fwlio_RxTx_control: SCK_descriptors[i][0] = %d\n", SCK_descriptors[channel][0]) ;
117  printf ("fwlio_RxTx_control: SCK_descriptors[i][1] = %d\n", SCK_descriptors[channel][1]) ;
118  printf ("fwlio_RxTx_control: SCK_port[i] = %d\n", SCK_port[channel]) ;
119  }
120  if (first_time != 0 ) {
121  int i;
122  for (i=0; i<MAX_SERVICE_CHANNELS; i++) {
123  service_status[i] = RxTx_STOP ;
124  service_justSink[i] = 0 ;
125  service_wanted[i] = FALSE;
126  service_connected[i] = FALSE;
127  service_failed[i] = FALSE;
128  service_onclose[i] = FALSE ;
129  service_verbose[i] = SOCKET_SERVICE_DEFAULT_VERBOSE ;
130  SCK_descriptors[i][0] = -1 ;
131  SCK_descriptors[i][1] = -1 ;
132  SCK_port[i] = -1 ;
133  }
134  SCK_port[CHANNEL_EAI] = EAIBASESOCKET ;
135  }
136  first_time = 0 ;
137 
138  /*
139  * In general, this function will just return the original action code, except:
140  * It will return 0 if the action was not a valid state request,
141  * It will return N if the control action requires that (for example the state code)
142  */
143  if( RxTx_STOP == action && service_status[channel] != RxTx_STOP) {
144  if (service_verbose[channel]) {
145  printf ("Shutting down the socket on logical channel %d\n",channel);
146  }
147 
148  if (service_connected[channel] && channel == CHANNEL_EAI) {
149  char *tmpstr = MALLOC(void *, 10);
150  strcpy(tmpstr,"QUIT\n\n\n");
151  fwlio_RxTx_sendbuffer(__FILE__,__LINE__,channel, tmpstr); //"QUIT\n\n\n");
152  FREE(tmpstr);
153  }
154  service_status[channel]=RxTx_STOP;
155  }
156  if( RxTx_START == action) {
157 
158  /* already wanted? if so, just return */
159  if (service_wanted[channel] && service_status[channel] != RxTx_STOP) return RxTx_START;
160 
161  /* so we know we want EAI */
162  service_wanted[channel] = TRUE;
163 
164  /* have we already started? */
165  if (!service_connected[channel]) {
166  int EAIsockfd = -1; /* main TCP socket fd*/
167  int EAIlistenfd = -1; /* listen to this one for an incoming connection*/
168  service_failed[channel] = !(privSocketSetup(channel, &EAIsockfd, &EAIlistenfd));
169  if(service_failed[channel]) {
170  return 0;
171  } else {
172  SCK_descriptors[channel][MAINSOCK_FD] = EAIsockfd ;
173  SCK_descriptors[channel][CLIENT_FD] = EAIlistenfd ;
174  service_status[channel] = RxTx_REFRESH;
175  }
176  }
177  }
178  if( RxTx_REFRESH == action) {
179  int EAIsockfd, EAIlistenfd;
180  int E_SOCK_bufcount;
181  int E_SOCK_bufsize;
182  char *E_SOCK_buffer;
183 
184  if (!service_wanted[channel]) return 0;
185 
186  EAIsockfd = SCK_descriptors[channel][MAINSOCK_FD] ;
187  EAIlistenfd = SCK_descriptors[channel][CLIENT_FD] ;
188  if (!service_connected[channel]) {
189  service_failed[channel] = !(privSocketSetup(channel,&EAIsockfd,&EAIlistenfd));
190  if(service_failed[channel]) {
191  return 0;
192  } else {
193  SCK_descriptors[channel][CLIENT_FD] = EAIlistenfd ;
194  service_status[channel] = RxTx_REFRESH;
195  }
196  }
197 #ifdef SKIP
198 JAS - service_connected is a boolean, how can it be greater than 1?
199 JAS if (!(service_connected[channel] > 1)) {
200 JAS if (service_verbose[channel]) {
201 JAS printf ("Still no client connection on channel %d\n",channel);
202 JAS }
203 JAS return 0;
204 JAS }
205 #endif //SKIP
206 
207  /* have we closed connection? */
208  if(SCK_descriptors[channel][CLIENT_FD] < 0) return 0;
209 
210  E_SOCK_bufcount = sock_bufcount[channel];
211  E_SOCK_bufsize = sock_bufsize[channel] ;
212  E_SOCK_buffer = sock_buffers[channel] ;
213 
214  /* EBUFFLOCK; */
215  sock_buffers[channel] = privSocketRead(channel,E_SOCK_buffer,&E_SOCK_bufcount, &E_SOCK_bufsize, &EAIlistenfd);
216  if (service_verbose[channel] > 1) {
217  printf ("Buffer(%d) addr %p\n",channel,sock_buffers[channel] );
218  }
219  /* printf ("read, E_SOCK_bufcount %d E_SOCK_bufsize %d\n",E_SOCK_bufcount, E_SOCK_bufsize); */
220  if(service_justSink[channel] == 1) E_SOCK_bufcount = 0;
221  sock_bufcount[channel] = E_SOCK_bufcount ;
222  sock_bufsize[channel] = E_SOCK_bufsize ;
223 
224  /* make this into a C string */
225  sock_buffers[channel][sock_bufcount[channel]] = 0;
226  /* EBUFFUNLOCK; */
227  if (service_verbose[channel] > 0) {
228  if (sock_bufcount[channel]) {
229  printf ("fwlio_RxTx_control: sock_bufcount[%d] = %d\nData is :%s:\n\n",
230  channel,
231  sock_bufcount[channel],
232  sock_buffers[channel]);
233  }
234  }
235  return sock_bufcount[channel] ;
236 
237  }
238  if( RxTx_STOP_IF_DISCONNECT == action) {
239  service_onclose[channel] = TRUE ;
240  }
241  if( RxTx_EMPTY == action) {
242  sock_bufcount[channel] = 0;
243  sock_buffers[channel][sock_bufcount[channel]] = 0;
244  }
245  if( RxTx_MOREVERBOSE == action) {
246  service_verbose[channel] += 1 ;
247  }
248  if( RxTx_GET_VERBOSITY == action) {
249  return service_verbose[channel] ;
250  }
251  if( RxTx_SILENT == action) {
252  service_verbose[channel] = 0 ;
253  }
254  if( RxTx_SINK == action) {
255  service_justSink[channel] = 1;
256  }
257  if( RxTx_PENDING == action) {
258  /* we might make this a bit more flexble */
259  if (service_verbose[channel] > 0) {
260  printf ("fwlio_RxTx_control: sock_bufcount[%d] (addr %p) = %d\n",
261  channel, sock_buffers[channel], sock_bufcount[channel]) ;
262  }
263  return sock_bufcount[channel] ;
264  }
265  if( RxTx_STATE == action) {
266  return service_status[channel] ;
267  }
268  if (service_verbose[channel] > 1) {
269  printf ("fwlio_RxTx_control() END:\n");
270  printf ("fwlio_RxTx_control: service_status[i] = %d\n", service_status[channel]) ;
271  printf ("fwlio_RxTx_control: service_justSink[i] = %d\n", service_justSink[channel]) ;
272  printf ("fwlio_RxTx_control: service_wanted[i] = %d\n", service_wanted[channel]) ;
273  printf ("fwlio_RxTx_control: service_connected[i] = %d\n", service_connected[channel]) ;
274  printf ("fwlio_RxTx_control: service_failed[i] = %d\n", service_failed[channel]) ;
275  printf ("fwlio_RxTx_control: service_onclose[i] = %d\n", service_onclose[channel]) ;
276  printf ("fwlio_RxTx_control: SCK_descriptors[i][0] = %d\n", SCK_descriptors[channel][0]) ;
277  printf ("fwlio_RxTx_control: SCK_descriptors[i][1] = %d\n", SCK_descriptors[channel][1]) ;
278  printf ("fwlio_RxTx_control: SCK_port[i] = %d\n", SCK_port[channel]) ;
279  printf ("fwlio_RxTx_control: sock_bufcount[%d] (addr %p) = length %d\n\n",
280  channel, sock_buffers[channel], sock_bufcount[channel]) ;
281  }
282 
283  return action ;
284 }
285 
286 char * fwlio_RxTx_waitfor(int channel, char *str) {
287  return strstr(sock_buffers[channel], str);
288 }
289 
290 char *fwlio_RxTx_getbuffer(int channel) {
291 
292  char *tmpStr = MALLOC(char *, sock_bufcount[channel] + 1);
293  if (service_verbose[channel]) {
294  printf ("fwlio_RxTx_getbuffer(%d)\n", channel);
295  printf ("fwlio_RxTx_getbuffer: Copy %d chars in buffer(%d) from addr %p to %p\n",sock_bufcount[channel],channel,sock_buffers[channel] ,tmpStr );
296  }
297 
298  if (!tmpStr)
299  return NULL;
300 
301  memcpy(tmpStr, sock_buffers[channel], sock_bufcount[channel]);
302  tmpStr[sock_bufcount[channel]] = '\0';
303  memset(sock_buffers[channel], 0, sock_bufcount[channel]);
304  sock_bufcount[channel] = 0 ;
305 
306  if (service_verbose[channel]) {
307  printf ("fwlio_RxTx_getbuffer: return %s\n\n",tmpStr );
308  }
309  return tmpStr;
310 }
311 
312 void fwlio_RxTx_sendbuffer(char *fromFile, int fromline, int channel, char *str) {
313  size_t n;
314 
315  /* add a trailing newline */
316  strcat (str,"\n");
317 
318  if (service_verbose[channel]) {
319  printf ("fwlio_RxTx_sendbuffer(%s,%d,%d,..), sending :\n%s\n(on FD %d)\n",fromFile,fromline,channel,str,SCK_descriptors[channel][CLIENT_FD]);
320  }
321 
322 #ifdef _MSC_VER
323  n = send(SCK_descriptors[channel][CLIENT_FD], str, (unsigned int) strlen(str),0);
324 #else
325  /* n = write (SCK_descriptors[channel][CLIENT_FD], (const void *)str, strlen(str)); */
326  n = write (SCK_descriptors[channel][CLIENT_FD], str, strlen(str));
327 #endif
328  if (service_verbose[channel]) {
329  printf ("fwlio_RxTx_sendbuffer(...%d,..), wrote %d 'chars'\n",channel,(int)n);
330  }
331  if (n<strlen(str)) {
332  printf ("fwlio_RxTx_sendbuffer(...%d,..) write, expected to write %d, actually wrote %d\n",channel,(int)n,(int)strlen(str));
333  }
334 }
335 
336 /* **************************************************************
337  * Private low level funtions
338  * ************************************************************** */
339 
340 /* open the socket connection - we open as a TCP server, and will find a free socket */
341 /* EAI will have a socket increment of 0; Java Class invocations will have 1 + */
342 int privSocketSetup(int channel, int *ANONsocketfd, int *ANONlistenfd) {
343  int len;
344  const int on=1;
345 #ifdef _MSC_VER
346  #define socklen_t int
347  int err;
348 #else
349  int flags;
350 #endif
351 
352  struct sockaddr_in servaddr;
353 
354  /* if ((service_failed[channel]) && (channel==0)) return FALSE; */
355  if ((service_failed[channel])) return FALSE;
356 
357  if ((*ANONsocketfd) < 0) {
358  /* step 1 - create socket*/
359 #ifdef _MSC_VER
360  static int wsaStarted;
361  if(wsaStarted == 0)
362  {
363  WSADATA wsaData;
364 
365  /* Initialize Winsock - load correct dll */
366  err = WSAStartup(MAKEWORD(2,2), &wsaData);
367  if (err != 0) {
368  printf("WSAStartup failed: %d\n", err);
369  return FALSE;
370  }
371  wsaStarted = 1;
372  }
373 #endif
374  if (((*ANONsocketfd) = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
375  printf ("WRL_Server: socket error\n");
376 #ifdef _MSC_VER
377  err = WSAGetLastError();
378  printf("WSAGetLastError =%d\n",err);
379  if(err == WSANOTINITIALISED) printf(" WSA Not Initialized - not a successful WSAStartup\n");
380 
381 #endif
382  loopFlags &= ~NO_EAI_CLASS;
383  return FALSE;
384  }
385 
386  setsockopt ((*ANONsocketfd), SOL_SOCKET, SO_REUSEADDR, &on, (socklen_t) sizeof(on));
387 
388 #ifdef _MSC_VER
389  /* int ioctlsocket(SOCKET s,long cmd, u_long* argp); http://msdn.microsoft.com/en-us/library/ms738573(VS.85).aspx */
390  {
391  unsigned long iMode = 1; /* nonzero is blocking */
392  ioctlsocket((*ANONsocketfd), FIONBIO, &iMode);
393  }
394 
395 #else
396  if ((flags=fcntl((*ANONsocketfd),F_GETFL,0)) < 0) {
397  printf ("EAIServer: trouble gettingsocket flags\n");
398  loopFlags &= ~NO_EAI_CLASS;
399  return FALSE;
400  } else {
401  flags |= O_NONBLOCK;
402 
403  if (fcntl((*ANONsocketfd), F_SETFL, flags) < 0) {
404  printf ("EAIServer: trouble setting non-blocking socket\n");
405  loopFlags &= ~NO_EAI_CLASS;
406  return FALSE;
407  }
408  }
409 #endif
410  if (service_verbose[channel]) {
411  printf ("privSocketSetup - socket made\n");
412  }
413 
414 
415  /* step 2 - bind to socket*/
416  memset(&servaddr, 0, sizeof(servaddr));
417  servaddr.sin_family = AF_INET;
418  servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
419  servaddr.sin_port = htons(SCK_port[channel]);
420  if (service_verbose[channel]) {
421  printf ("FreeWRL socket server binding to socket on port %d for channel %d\n",SCK_port[channel], channel);
422  }
423 
424  while (bind((*ANONsocketfd), (struct sockaddr *) &servaddr, (socklen_t) sizeof(servaddr)) < 0) {
425  loopFlags &= ~NO_EAI_CLASS;
426  return FALSE;
427  }
428 
429  if (service_verbose[channel]) {
430  printf ("FreeWRL socket server: bound to socket %d\n",SCK_port[channel]);
431  }
432 
433 
434  /* step 3 - listen*/
435 
436  if (listen((*ANONsocketfd), 1024) < 0) {
437  printf ("FreeWRL socket server: listen error\n");
438  loopFlags &= ~NO_EAI_CLASS;
439  return FALSE;
440  }
441  }
442  if (service_verbose[channel]) {
443  if ( (*ANONsocketfd) >= 0 ) {
444  if (service_verbose[channel] > 1) {
445  printf("We have a valid socket fd, %d",(*ANONsocketfd)) ;
446  }
447  }
448  if ( (*ANONlistenfd) >= 0 ) {
449  printf(" and we have a client connected fd, %d\n",(*ANONlistenfd)) ;
450  } else {
451  if (service_verbose[channel] > 1) {
452  printf(" but no client connection (yet)\n") ;
453  }
454  }
455  }
456 
457  if (((*ANONsocketfd) >=0 ) && ((*ANONlistenfd)<0)) {
458  /* step 4 - accept*/
459  if (service_verbose[channel]>1) {
460  printf("We are going to attempt a non-blocking accept()..\n") ;
461  }
462  len = (int) sizeof(cliaddr);
463 #ifdef _MSC_VER
464  if ( ((*ANONlistenfd) = accept((*ANONsocketfd), (struct sockaddr *) &cliaddr, (int *)&len)) < 0) {
465 #else
466  if ( ((*ANONlistenfd) = accept((*ANONsocketfd), (struct sockaddr *) &cliaddr, (socklen_t *)&len)) < 0) {
467 #endif
468  if (service_verbose[channel]>1) {
469  if (!(loopFlags&NO_CLIENT_CONNECTED)) {
470  printf ("FreeWRL socket server: no client yet\n");
471  loopFlags |= NO_CLIENT_CONNECTED;
472  }
473  }
474 
475  } else {
476  loopFlags &= ~NO_CLIENT_CONNECTED;
477  if (service_verbose[channel]) {
478  printf ("FreeWRL socket server: we have a client\n");
479  }
480  }
481  }
482 
483 
484  /* are we ok, ? */
485  if ((*ANONlistenfd) >=0) {
486  if(!service_connected[channel]) {
487  SCK_descriptors[channel][1] = (*ANONlistenfd) ;
488  /* allocate memory for input buffer */
489  sock_bufcount[channel] = 0;
490  sock_bufsize[channel] = 2 * EAIREADSIZE; /* initial size*/
491  if (service_verbose[channel]) {
492  printf ("FreeWRL socket server: malloc a buffer,%d\n",sock_bufsize[channel]);
493  }
494  /* EBUFFLOCK; */
495  sock_buffers[channel] = MALLOC(char *, sock_bufsize[channel] * sizeof (char));
496  /* EBUFFUNLOCK; */
497 
498  /* seems like we are up and running now, and waiting for a command */
499  service_connected[channel] = TRUE;
500  } else {
501  printf ("FreeWRL socket server: Why are we in %s,%d? we should not be here!!\n",__FILE__,__LINE__);
502  }
503  }
504  /* printf ("FreeWRL socket server: privSocketSetup returning TRUE\n");*/
505 
506  if (service_verbose[channel]) {
507  if ( !(loopFlags&NO_EAI_CLASS)) {
508  printf ("FreeWRL socket server: privSocketSetup returning TRUE\n");
509  loopFlags |= NO_EAI_CLASS;
510  }
511  }
512 
513  return TRUE;
514 }
515 
516 /* read in from the socket. pass in -
517  pointer to buffer,
518  pointer to buffer index
519  pointer to max size,
520  pointer to socket to listen to
521 
522  return the char pointer - it may have been REALLOC'd */
523 
524 
525 char *privSocketRead(int channel, char *bf, int *bfct, int *bfsz, int *EAIlistenfd) {
526  int retval, oldRetval;
527 
528  if (service_verbose[channel] > 1) {
529  printf ("privSocketRead (polling), listenfd %d, buffer addr %p\n",(*EAIlistenfd),(void *) bf);
530  }
531  retval = FALSE;
532  do {
533  tv2.tv_sec = 0;
534  tv2.tv_usec = 0;
535  FD_ZERO(&rfds2);
536  FD_SET((*EAIlistenfd), &rfds2);
537 
538  oldRetval = retval;
539  retval = select((*EAIlistenfd)+1, &rfds2, NULL, NULL, &tv2);
540  if (service_verbose[channel] > 1) printf ("select retval %d\n",retval);
541 
542  if (retval != oldRetval) {
543  loopFlags &= NO_RETVAL_CHANGE;
544  }
545 
546  if (service_verbose[channel] > 1) {
547  if (!(loopFlags&NO_RETVAL_CHANGE)) {
548  printf ("privSocketRead, retval %d\n",retval);
549  loopFlags |= NO_RETVAL_CHANGE;
550  }
551  }
552 
553 
554  if (retval) {
555 #ifdef _MSC_VER
556  retval = recv((*EAIlistenfd), &bf[(*bfct)],EAIREADSIZE,0);
557 #else
558  retval = (int) read ((*EAIlistenfd), &bf[(*bfct)],EAIREADSIZE);
559 #endif
560  if (retval <= 0) {
561  if (service_verbose[channel]) {
562  printf ("privSocketRead, client is gone!\n");
563  }
564 
565  /*perror("READ_EAISOCKET");*/
566  /* client disappeared*/
567 #ifdef _MSC_VER
568  closesocket((*EAIlistenfd));
569  WSACleanup();
570 #else
571 
572  close ((*EAIlistenfd));
573 #endif
574  (*EAIlistenfd) = -1;
575  SCK_descriptors[channel][0] = -1 ;
576  SCK_descriptors[channel][1] = -1 ;
577  service_status[channel] = RxTx_STOP ;
578  service_wanted[channel] = FALSE;
579  service_connected[channel] = FALSE;
580  service_failed[channel] = FALSE;
581 
582  if(service_onclose[channel] == TRUE) {
583  /* And, lets just exit FreeWRL*/
584  printf ("FreeWRL:EAI socket closed, exiting...\n");
585  fwl_doQuit(__FILE__,__LINE__);
586  return (bf);
587  } else {
588  return (bf);
589  }
590  }
591 
592  if (service_verbose[channel]>1) {
593  char tmpBuff1[EAIREADSIZE];
594  strncpy(tmpBuff1,&bf[(*bfct)],retval);
595  tmpBuff1[retval] = '\0';
596  printf ("privSocketRead %d bytes, max %d bfct %d input=<%s>\n",
597  retval,EAIREADSIZE, *bfct,tmpBuff1);/*, &bf[(*bfct)]);*/
598  }
599 
600 
601  (*bfct) += retval;
602 
603  if (((*bfsz) - (*bfct)) <= EAIREADSIZE) {
604  if (service_verbose[channel])
605  printf ("privSocketRead: HAVE TO REALLOC INPUT MEMORY:bf %p bfsz %d bfct %d\n",bf,*bfsz, *bfct);
606  (*bfsz) += EAIREADSIZE;
607  if (service_verbose[channel])
608  printf ("privSocketRead: bfsz now %d\n",*bfsz);
609  bf = (char *)REALLOC (bf, (unsigned int) (*bfsz));
610  if (service_verbose[channel])
611  printf ("privSocketRead: REALLOC complete\n");
612  }
613  }
614  if (service_verbose[channel] > 1) {
615  printf ("Buffer addr %p\n",(void *) bf);
616  }
617  } while (retval);
618  return (bf);
619 }
620 #endif //EXCLUDE_EAI
621