diff --git a/src/common/header/common.h b/src/common/header/common.h index 13f0d273..18b1e89d 100644 --- a/src/common/header/common.h +++ b/src/common/header/common.h @@ -467,7 +467,6 @@ typedef struct unsigned short port; } netadr_t; -void NET_Init (void); void NET_Shutdown (void); void NET_Config (qboolean multiplayer); diff --git a/src/common/misc.c b/src/common/misc.c index c6dc4996..ff0f438e 100644 --- a/src/common/misc.c +++ b/src/common/misc.c @@ -247,7 +247,6 @@ void Qcommon_Init (int argc, char **argv) Sys_Init (); - NET_Init (); Netchan_Init (); SV_Init (); diff --git a/src/posix/network.c b/src/posix/network.c index e6537736..9b084061 100644 --- a/src/posix/network.c +++ b/src/posix/network.c @@ -1,22 +1,28 @@ /* -Copyright (C) 1997-2001 Id Software, Inc. - -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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ + * Copyright (C) 1997-2001 Id Software, Inc. + * + * 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * ======================================================================= + * + * Low level network code, based upon the BSD socket api. + * + * ======================================================================= + */ #include "../common/header/common.h" @@ -31,525 +37,529 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include -netadr_t net_local_adr; +netadr_t net_local_adr; -#define LOOPBACK 0x7f000001 - -#define MAX_LOOPBACK 4 +#define LOOPBACK 0x7f000001 +#define MAX_LOOPBACK 4 typedef struct { - byte data[MAX_MSGLEN]; - int datalen; + byte data [ MAX_MSGLEN ]; + int datalen; } loopmsg_t; typedef struct { - loopmsg_t msgs[MAX_LOOPBACK]; - int get, send; + loopmsg_t msgs [ MAX_LOOPBACK ]; + int get, send; } loopback_t; -loopback_t loopbacks[2]; -int ip_sockets[2]; -int ipx_sockets[2]; +loopback_t loopbacks [ 2 ]; +int ip_sockets [ 2 ]; +int ipx_sockets [ 2 ]; -int NET_Socket (char *net_interface, int port); -char *NET_ErrorString (void); +int NET_Socket ( char *net_interface, int port ); +char *NET_ErrorString ( void ); -//============================================================================= - -void NetadrToSockadr (netadr_t *a, struct sockaddr_in *s) +void +NetadrToSockadr ( netadr_t *a, struct sockaddr_in *s ) { - memset (s, 0, sizeof(*s)); + memset( s, 0, sizeof ( *s ) ); - if (a->type == NA_BROADCAST) + if ( a->type == NA_BROADCAST ) { s->sin_family = AF_INET; s->sin_port = a->port; - *(int *)&s->sin_addr = -1; + *(int *) &s->sin_addr = -1; } - else if (a->type == NA_IP) + else if ( a->type == NA_IP ) { s->sin_family = AF_INET; - *(int *)&s->sin_addr = *(int *)&a->ip; + *(int *) &s->sin_addr = *(int *) &a->ip; s->sin_port = a->port; } } -void SockadrToNetadr (struct sockaddr_in *s, netadr_t *a) +void +SockadrToNetadr ( struct sockaddr_in *s, netadr_t *a ) { - *(int *)&a->ip = *(int *)&s->sin_addr; + *(int *) &a->ip = *(int *) &s->sin_addr; a->port = s->sin_port; a->type = NA_IP; } -qboolean NET_CompareAdr (netadr_t a, netadr_t b) +qboolean +NET_CompareAdr ( netadr_t a, netadr_t b ) { - if (a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] && a.ip[3] == b.ip[3] && a.port == b.port) - return true; - return false; + if ( ( a.ip [ 0 ] == b.ip [ 0 ] ) && ( a.ip [ 1 ] == b.ip [ 1 ] ) && ( a.ip [ 2 ] == b.ip [ 2 ] ) && + ( a.ip [ 3 ] == b.ip [ 3 ] ) && ( a.port == b.port ) ) + { + return ( true ); + } + + return ( false ); } /* -=================== -NET_CompareBaseAdr - -Compares without the port -=================== -*/ -qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b) + * Compares without the port + */ +qboolean +NET_CompareBaseAdr ( netadr_t a, netadr_t b ) { - if (a.type != b.type) - return false; - - if (a.type == NA_LOOPBACK) - return true; - - if (a.type == NA_IP) + if ( a.type != b.type ) { - if (a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] && a.ip[3] == b.ip[3]) - return true; - return false; + return ( false ); } - if (a.type == NA_IPX) + if ( a.type == NA_LOOPBACK ) { - if ((memcmp(a.ipx, b.ipx, 10) == 0)) - return true; - return false; + return ( true ); } - return false; + + if ( a.type == NA_IP ) + { + if ( ( a.ip [ 0 ] == b.ip [ 0 ] ) && ( a.ip [ 1 ] == b.ip [ 1 ] ) && ( a.ip [ 2 ] == b.ip [ 2 ] ) && + ( a.ip [ 3 ] == b.ip [ 3 ] ) ) + { + return ( true ); + } + + return ( false ); + } + + if ( a.type == NA_IPX ) + { + if ( ( memcmp( a.ipx, b.ipx, 10 ) == 0 ) ) + { + return ( true ); + } + + return ( false ); + } + + return ( false ); } -char *NET_AdrToString (netadr_t a) +char * +NET_AdrToString ( netadr_t a ) { - static char s[64]; - - Com_sprintf (s, sizeof(s), "%i.%i.%i.%i:%i", a.ip[0], a.ip[1], a.ip[2], a.ip[3], ntohs(a.port)); + static char s [ 64 ]; - return s; + Com_sprintf( s, sizeof ( s ), "%i.%i.%i.%i:%i", a.ip [ 0 ], a.ip [ 1 ], a.ip [ 2 ], a.ip [ 3 ], ntohs( a.port ) ); + + return ( s ); } -char *NET_BaseAdrToString (netadr_t a) +char * +NET_BaseAdrToString ( netadr_t a ) { - static char s[64]; - - Com_sprintf (s, sizeof(s), "%i.%i.%i.%i", a.ip[0], a.ip[1], a.ip[2], a.ip[3]); + static char s [ 64 ]; - return s; + Com_sprintf( s, sizeof ( s ), "%i.%i.%i.%i", a.ip [ 0 ], a.ip [ 1 ], a.ip [ 2 ], a.ip [ 3 ] ); + + return ( s ); } -/* -============= -NET_StringToAdr - -localhost -idnewt -idnewt:28000 -192.246.40.70 -192.246.40.70:28000 -============= -*/ -qboolean NET_StringToSockaddr (char *s, struct sockaddr *sadr) +qboolean +NET_StringToSockaddr ( char *s, struct sockaddr *sadr ) { - struct hostent *h; - char *colon; - char copy[128]; - - memset (sadr, 0, sizeof(*sadr)); - ((struct sockaddr_in *)sadr)->sin_family = AF_INET; - - ((struct sockaddr_in *)sadr)->sin_port = 0; + struct hostent *h; + char *colon; + char copy [ 128 ]; - strcpy (copy, s); - // strip off a trailing :port if present - for (colon = copy ; *colon ; colon++) - if (*colon == ':') + memset( sadr, 0, sizeof ( *sadr ) ); + ( (struct sockaddr_in *) sadr )->sin_family = AF_INET; + + ( (struct sockaddr_in *) sadr )->sin_port = 0; + + strcpy( copy, s ); + + /* strip off a trailing :port if present */ + for ( colon = copy; *colon; colon++ ) + { + if ( *colon == ':' ) { *colon = 0; - ((struct sockaddr_in *)sadr)->sin_port = htons((short)atoi(colon+1)); + ( (struct sockaddr_in *) sadr )->sin_port = htons( (short) atoi( colon + 1 ) ); } - - if (copy[0] >= '0' && copy[0] <= '9') + } + + if ( ( copy [ 0 ] >= '0' ) && ( copy [ 0 ] <= '9' ) ) { - *(int *)&((struct sockaddr_in *)sadr)->sin_addr = inet_addr(copy); + *(int *) &( (struct sockaddr_in *) sadr )->sin_addr = inet_addr( copy ); } else { - if (! (h = gethostbyname(copy)) ) - return 0; - *(int *)&((struct sockaddr_in *)sadr)->sin_addr = *(int *)h->h_addr_list[0]; + if ( !( h = gethostbyname( copy ) ) ) + { + return ( 0 ); + } + + *(int *) &( (struct sockaddr_in *) sadr )->sin_addr = *(int *) h->h_addr_list [ 0 ]; } - - return true; + + return ( true ); } -/* -============= -NET_StringToAdr - -localhost -idnewt -idnewt:28000 -192.246.40.70 -192.246.40.70:28000 -============= -*/ -qboolean NET_StringToAdr (char *s, netadr_t *a) +qboolean +NET_StringToAdr ( char *s, netadr_t *a ) { struct sockaddr_in sadr; - - if (!strcmp (s, "localhost")) + + if ( !strcmp( s, "localhost" ) ) { - memset (a, 0, sizeof(*a)); + memset( a, 0, sizeof ( *a ) ); a->type = NA_LOOPBACK; - return true; + return ( true ); } - if (!NET_StringToSockaddr (s, (struct sockaddr *)&sadr)) - return false; - - SockadrToNetadr (&sadr, a); + if ( !NET_StringToSockaddr( s, (struct sockaddr *) &sadr ) ) + { + return ( false ); + } - return true; + SockadrToNetadr( &sadr, a ); + + return ( true ); } - -qboolean NET_IsLocalAddress (netadr_t adr) +qboolean +NET_IsLocalAddress ( netadr_t adr ) { - return NET_CompareAdr (adr, net_local_adr); + return ( NET_CompareAdr( adr, net_local_adr ) ); } -/* -============================================================================= - -LOOPBACK BUFFERS FOR LOCAL PLAYER - -============================================================================= -*/ - -qboolean NET_GetLoopPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message) +qboolean +NET_GetLoopPacket ( netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message ) { - int i; - loopback_t *loop; + int i; + loopback_t *loop; - loop = &loopbacks[sock]; + loop = &loopbacks [ sock ]; - if (loop->send - loop->get > MAX_LOOPBACK) + if ( loop->send - loop->get > MAX_LOOPBACK ) + { loop->get = loop->send - MAX_LOOPBACK; + } - if (loop->get >= loop->send) - return false; + if ( loop->get >= loop->send ) + { + return ( false ); + } - i = loop->get & (MAX_LOOPBACK-1); + i = loop->get & ( MAX_LOOPBACK - 1 ); loop->get++; - memcpy (net_message->data, loop->msgs[i].data, loop->msgs[i].datalen); - net_message->cursize = loop->msgs[i].datalen; + memcpy( net_message->data, loop->msgs [ i ].data, loop->msgs [ i ].datalen ); + net_message->cursize = loop->msgs [ i ].datalen; *net_from = net_local_adr; - return true; - + return ( true ); } - -void NET_SendLoopPacket (netsrc_t sock, int length, void *data, netadr_t to) +void +NET_SendLoopPacket ( netsrc_t sock, int length, void *data, netadr_t to ) { - int i; - loopback_t *loop; + int i; + loopback_t *loop; - loop = &loopbacks[sock^1]; + loop = &loopbacks [ sock ^ 1 ]; - i = loop->send & (MAX_LOOPBACK-1); + i = loop->send & ( MAX_LOOPBACK - 1 ); loop->send++; - memcpy (loop->msgs[i].data, data, length); - loop->msgs[i].datalen = length; + memcpy( loop->msgs [ i ].data, data, length ); + loop->msgs [ i ].datalen = length; } -//============================================================================= - -qboolean NET_GetPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message) +qboolean +NET_GetPacket ( netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message ) { - int ret; - struct sockaddr_in from; - socklen_t fromlen; - int net_socket; - int protocol; - int err; + int ret; + struct sockaddr_in from; + socklen_t fromlen; + int net_socket; + int protocol; + int err; - if (NET_GetLoopPacket (sock, net_from, net_message)) - return true; - - for (protocol = 0 ; protocol < 2 ; protocol++) + if ( NET_GetLoopPacket( sock, net_from, net_message ) ) { - if (protocol == 0) - net_socket = ip_sockets[sock]; - else - net_socket = ipx_sockets[sock]; + return ( true ); + } - if (!net_socket) - continue; - - fromlen = sizeof(from); - ret = recvfrom (net_socket, net_message->data, net_message->maxsize - , 0, (struct sockaddr *)&from, &fromlen); - - SockadrToNetadr (&from, net_from); - - if (ret == -1) + for ( protocol = 0; protocol < 2; protocol++ ) + { + if ( protocol == 0 ) { - err = errno; + net_socket = ip_sockets [ sock ]; + } + else + { + net_socket = ipx_sockets [ sock ]; + } - if (err == EWOULDBLOCK || err == ECONNREFUSED) - continue; - Com_Printf ("NET_GetPacket: %s from %s\n", NET_ErrorString(), - NET_AdrToString(*net_from)); + if ( !net_socket ) + { continue; } - if (ret == net_message->maxsize) + fromlen = sizeof ( from ); + ret = recvfrom( net_socket, net_message->data, net_message->maxsize, + 0, (struct sockaddr *) &from, &fromlen ); + + SockadrToNetadr( &from, net_from ); + + if ( ret == -1 ) { - Com_Printf ("Oversize packet from %s\n", NET_AdrToString (*net_from)); + err = errno; + + if ( ( err == EWOULDBLOCK ) || ( err == ECONNREFUSED ) ) + { + continue; + } + + Com_Printf( "NET_GetPacket: %s from %s\n", NET_ErrorString(), + NET_AdrToString( *net_from ) ); + continue; + } + + if ( ret == net_message->maxsize ) + { + Com_Printf( "Oversize packet from %s\n", NET_AdrToString( *net_from ) ); continue; } net_message->cursize = ret; - return true; + return ( true ); } - return false; + return ( false ); } -//============================================================================= - -void NET_SendPacket (netsrc_t sock, int length, void *data, netadr_t to) +void +NET_SendPacket ( netsrc_t sock, int length, void *data, netadr_t to ) { - int ret; - struct sockaddr_in addr; - int net_socket; + int ret; + struct sockaddr_in addr; + int net_socket; if ( to.type == NA_LOOPBACK ) { - NET_SendLoopPacket (sock, length, data, to); + NET_SendLoopPacket( sock, length, data, to ); return; } - if (to.type == NA_BROADCAST) + if ( to.type == NA_BROADCAST ) { - net_socket = ip_sockets[sock]; - if (!net_socket) - return; - } - else if (to.type == NA_IP) - { - net_socket = ip_sockets[sock]; - if (!net_socket) - return; - } - else if (to.type == NA_IPX) - { - net_socket = ipx_sockets[sock]; - if (!net_socket) - return; - } - else if (to.type == NA_BROADCAST_IPX) - { - net_socket = ipx_sockets[sock]; - if (!net_socket) - return; - } - else - { - Com_Error (ERR_FATAL, "NET_SendPacket: bad address type"); - return; - } + net_socket = ip_sockets [ sock ]; - NetadrToSockadr (&to, &addr); - - ret = sendto (net_socket, data, length, 0, (struct sockaddr *)&addr, sizeof(addr) ); - if (ret == -1) - { - Com_Printf ("NET_SendPacket ERROR: %s to %s\n", NET_ErrorString(), - NET_AdrToString (to)); - } -} - -//============================================================================= - -/* -==================== -NET_OpenIP -==================== -*/ -void NET_OpenIP (void) -{ - cvar_t *port, *ip; - - port = Cvar_Get ("port", va("%i", PORT_SERVER), CVAR_NOSET); - ip = Cvar_Get ("ip", "localhost", CVAR_NOSET); - - if (!ip_sockets[NS_SERVER]) - ip_sockets[NS_SERVER] = NET_Socket (ip->string, port->value); - if (!ip_sockets[NS_CLIENT]) - ip_sockets[NS_CLIENT] = NET_Socket (ip->string, PORT_ANY); -} - -/* -==================== -NET_OpenIPX -==================== -*/ -void NET_OpenIPX (void) -{ -} - - -/* -==================== -NET_Config - -A single player game will only use the loopback code -==================== -*/ -void NET_Config (qboolean multiplayer) -{ - int i; - - if (!multiplayer) - { // shut down any existing sockets - for (i=0 ; i<2 ; i++) + if ( !net_socket ) { - if (ip_sockets[i]) + return; + } + } + else if ( to.type == NA_IP ) + { + net_socket = ip_sockets [ sock ]; + + if ( !net_socket ) + { + return; + } + } + else if ( to.type == NA_IPX ) + { + net_socket = ipx_sockets [ sock ]; + + if ( !net_socket ) + { + return; + } + } + else if ( to.type == NA_BROADCAST_IPX ) + { + net_socket = ipx_sockets [ sock ]; + + if ( !net_socket ) + { + return; + } + } + else + { + Com_Error( ERR_FATAL, "NET_SendPacket: bad address type" ); + return; + } + + NetadrToSockadr( &to, &addr ); + + ret = sendto( net_socket, data, length, 0, (struct sockaddr *) &addr, sizeof ( addr ) ); + + if ( ret == -1 ) + { + Com_Printf( "NET_SendPacket ERROR: %s to %s\n", NET_ErrorString(), + NET_AdrToString( to ) ); + } +} + +void +NET_OpenIP ( void ) +{ + cvar_t *port, *ip; + + port = Cvar_Get( "port", va( "%i", PORT_SERVER ), CVAR_NOSET ); + ip = Cvar_Get( "ip", "localhost", CVAR_NOSET ); + + if ( !ip_sockets [ NS_SERVER ] ) + { + ip_sockets [ NS_SERVER ] = NET_Socket( ip->string, port->value ); + } + + if ( !ip_sockets [ NS_CLIENT ] ) + { + ip_sockets [ NS_CLIENT ] = NET_Socket( ip->string, PORT_ANY ); + } +} + +/* + * A single player game will only use the loopback code + */ +void +NET_Config ( qboolean multiplayer ) +{ + int i; + + if ( !multiplayer ) + { /* shut down any existing sockets */ + for ( i = 0; i < 2; i++ ) + { + if ( ip_sockets [ i ] ) { - close (ip_sockets[i]); - ip_sockets[i] = 0; + close( ip_sockets [ i ] ); + ip_sockets [ i ] = 0; } - if (ipx_sockets[i]) + + if ( ipx_sockets [ i ] ) { - close (ipx_sockets[i]); - ipx_sockets[i] = 0; + close( ipx_sockets [ i ] ); + ipx_sockets [ i ] = 0; } } } else - { // open sockets - NET_OpenIP (); - NET_OpenIPX (); + { + /* open sockets */ + NET_OpenIP(); } } - -//=================================================================== - +/* =================================================================== */ /* -==================== -NET_Init -==================== -*/ -void NET_Init (void) -{ -} - - -/* -==================== -NET_Socket -==================== -*/ -int NET_Socket (char *net_interface, int port) + * ==================== + * NET_Socket + * ==================== + */ +int +NET_Socket ( char *net_interface, int port ) { int newsocket; struct sockaddr_in address; qboolean _true = true; - int i = 1; + int i = 1; - if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) + if ( ( newsocket = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP ) ) == -1 ) { - Com_Printf ("ERROR: UDP_OpenSocket: socket: %s", NET_ErrorString()); - return 0; + Com_Printf( "ERROR: UDP_OpenSocket: socket: %s", NET_ErrorString() ); + return ( 0 ); } - // make it non-blocking - if (ioctl (newsocket, FIONBIO, &_true) == -1) + /* make it non-blocking */ + if ( ioctl( newsocket, FIONBIO, &_true ) == -1 ) { - Com_Printf ("ERROR: UDP_OpenSocket: ioctl FIONBIO:%s\n", NET_ErrorString()); - return 0; + Com_Printf( "ERROR: UDP_OpenSocket: ioctl FIONBIO:%s\n", NET_ErrorString() ); + return ( 0 ); } - // make it broadcast capable - if (setsockopt(newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) == -1) + /* make it broadcast capable */ + if ( setsockopt( newsocket, SOL_SOCKET, SO_BROADCAST, (char *) &i, sizeof ( i ) ) == -1 ) { - Com_Printf ("ERROR: UDP_OpenSocket: setsockopt SO_BROADCAST:%s\n", NET_ErrorString()); - return 0; + Com_Printf( "ERROR: UDP_OpenSocket: setsockopt SO_BROADCAST:%s\n", NET_ErrorString() ); + return ( 0 ); } - if (!net_interface || !net_interface[0] || !strcasecmp(net_interface, "localhost")) + if ( !net_interface || !net_interface [ 0 ] || !strcasecmp( net_interface, "localhost" ) ) + { address.sin_addr.s_addr = INADDR_ANY; + } else - NET_StringToSockaddr (net_interface, (struct sockaddr *)&address); + { + NET_StringToSockaddr( net_interface, (struct sockaddr *) &address ); + } - if (port == PORT_ANY) + if ( port == PORT_ANY ) + { address.sin_port = 0; + } else - address.sin_port = htons((short)port); + { + address.sin_port = htons( (short) port ); + } address.sin_family = AF_INET; - if( bind (newsocket, (void *)&address, sizeof(address)) == -1) + if ( bind( newsocket, (void *) &address, sizeof ( address ) ) == -1 ) { - Com_Printf ("ERROR: UDP_OpenSocket: bind: %s\n", NET_ErrorString()); - close (newsocket); - return 0; + Com_Printf( "ERROR: UDP_OpenSocket: bind: %s\n", NET_ErrorString() ); + close( newsocket ); + return ( 0 ); } - return newsocket; + return ( newsocket ); } - -/* -==================== -NET_Shutdown -==================== -*/ -void NET_Shutdown (void) +void +NET_Shutdown ( void ) { - NET_Config (false); // close sockets + NET_Config( false ); /* close sockets */ } - -/* -==================== -NET_ErrorString -==================== -*/ -char *NET_ErrorString (void) +char * +NET_ErrorString ( void ) { - int code; + int code; code = errno; - return strerror (code); + return ( strerror( code ) ); } -// sleeps msec or until net socket is ready -void NET_Sleep(int msec) +/* + * sleeps msec or until net socket is ready + */ +void +NET_Sleep ( int msec ) { - struct timeval timeout; - fd_set fdset; + struct timeval timeout; + fd_set fdset; extern cvar_t *dedicated; extern qboolean stdin_active; - if (!ip_sockets[NS_SERVER] || (dedicated && !dedicated->value)) - return; // we're not a server, just run full speed + if ( !ip_sockets [ NS_SERVER ] || ( dedicated && !dedicated->value ) ) + { + return; /* we're not a server, just run full speed */ + } - FD_ZERO(&fdset); - if (stdin_active) - FD_SET(0, &fdset); // stdin is processed too - FD_SET(ip_sockets[NS_SERVER], &fdset); // network socket - timeout.tv_sec = msec/1000; - timeout.tv_usec = (msec%1000)*1000; - select(ip_sockets[NS_SERVER]+1, &fdset, NULL, NULL, &timeout); + FD_ZERO( &fdset ); + + if ( stdin_active ) + { + FD_SET( 0, &fdset ); /* stdin is processed too */ + } + + FD_SET( ip_sockets [ NS_SERVER ], &fdset ); /* network socket */ + timeout.tv_sec = msec / 1000; + timeout.tv_usec = ( msec % 1000 ) * 1000; + select( ip_sockets [ NS_SERVER ] + 1, &fdset, NULL, NULL, &timeout ); }