]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - libs/l_net/l_net.c
fix some strncpy use
[xonotic/netradiant.git] / libs / l_net / l_net.c
1 /*
2    Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3    For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5    This file is part of GtkRadiant.
6
7    GtkRadiant is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    GtkRadiant is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GtkRadiant; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 //====================================================================
23 //
24 // Name:                        l_net.c
25 // Function:            -
26 // Programmer:          MrElusive
27 // Last update:         -
28 // Tab size:            3
29 // Notes:
30 //====================================================================
31
32 #include "globaldefs.h"
33 #include <stdio.h>
34 #include <stdarg.h>
35 #include <string.h>
36 #include <stdlib.h>
37 #include "l_net.h"
38 #include "l_net_wins.h"
39
40 #if GDEF_DEBUG
41 void WinPrint( const char *str, ... ){
42         va_list argptr;
43         char text[4096];
44
45         va_start( argptr,str );
46         vsprintf( text, str, argptr );
47         va_end( argptr );
48
49         printf( "%s", text );
50 }
51 #else
52 void WinPrint( const char *str, ... ){
53 }
54 #endif
55
56 //===========================================================================
57 //
58 // Parameter:                           -
59 // Returns:                                     -
60 // Changes Globals:             -
61 //===========================================================================
62 void Net_SetAddressPort( address_t *address, int port ){
63         sockaddr_t addr;
64
65         WINS_StringToAddr( address->ip, &addr );
66         WINS_SetSocketPort( &addr, port );
67         strcpy( address->ip, WINS_AddrToString( &addr ) );
68 } //end of the function Net_SetAddressPort
69 //===========================================================================
70 //
71 // Parameter:                           -
72 // Returns:                                     -
73 // Changes Globals:             -
74 //===========================================================================
75 int Net_AddressCompare( address_t *addr1, address_t *addr2 ){
76 #if GDEF_OS_WINDOWS
77         return _stricmp( addr1->ip, addr2->ip );
78 #else
79         return strcasecmp( addr1->ip, addr2->ip );
80 #endif
81 } //end of the function Net_AddressCompare
82 //===========================================================================
83 //
84 // Parameter:                           -
85 // Returns:                                     -
86 // Changes Globals:             -
87 //===========================================================================
88 void Net_SocketToAddress( socket_t *sock, address_t *address ){
89         strcpy( address->ip, WINS_AddrToString( &sock->addr ) );
90 } //end of the function Net_SocketToAddress
91 //===========================================================================
92 //
93 // Parameter:                           -
94 // Returns:                                     -
95 // Changes Globals:             -
96 //===========================================================================
97 int Net_Send( socket_t *sock, netmessage_t *msg ){
98         int size;
99
100         size = msg->size;
101         msg->size = 0;
102         NMSG_WriteLong( msg, size - 4 );
103         msg->size = size;
104         //WinPrint("Net_Send: message of size %d\n", sendmsg.size);
105         return WINS_Write( sock->socket, msg->data, msg->size, NULL );
106 } //end of the function Net_SendSocketReliable
107 //===========================================================================
108 // returns the number of bytes recieved
109 // -1 on error
110 //
111 // Parameter:                           -
112 // Returns:                                     -
113 // Changes Globals:             -
114 //===========================================================================
115 int Net_Receive( socket_t *sock, netmessage_t *msg ){
116         int curread;
117
118         if ( sock->remaining > 0 ) {
119                 curread = WINS_Read( sock->socket, &sock->msg.data[sock->msg.size], sock->remaining, NULL );
120                 if ( curread == -1 ) {
121                         WinPrint( "Net_Receive: read error\n" );
122                         return -1;
123                 } //end if
124                 sock->remaining -= curread;
125                 sock->msg.size += curread;
126                 if ( sock->remaining <= 0 ) {
127                         sock->remaining = 0;
128                         memcpy( msg, &sock->msg, sizeof( netmessage_t ) );
129                         sock->msg.size = 0;
130                         return msg->size - 4;
131                 } //end if
132                 return 0;
133         } //end if
134         sock->msg.size = WINS_Read( sock->socket, sock->msg.data, 4, NULL );
135         if ( sock->msg.size == 0 ) {
136                 return 0;
137         }
138         if ( sock->msg.size == -1 ) {
139                 WinPrint( "Net_Receive: size header read error\n" );
140                 return -1;
141         } //end if
142           //WinPrint("Net_Receive: message size header %d\n", msg->size);
143         sock->msg.read = 0;
144         sock->remaining = NMSG_ReadLong( &sock->msg );
145         if ( sock->remaining == 0 ) {
146                 return 0;
147         }
148         if ( sock->remaining < 0 || sock->remaining > MAX_NETMESSAGE ) {
149                 WinPrint( "Net_Receive: invalid message size %d\n", sock->remaining );
150                 return -1;
151         } //end if
152           //try to read the message
153         curread = WINS_Read( sock->socket, &sock->msg.data[sock->msg.size], sock->remaining, NULL );
154         if ( curread == -1 ) {
155                 WinPrint( "Net_Receive: read error\n" );
156                 return -1;
157         } //end if
158         sock->remaining -= curread;
159         sock->msg.size += curread;
160         if ( sock->remaining <= 0 ) {
161                 sock->remaining = 0;
162                 memcpy( msg, &sock->msg, sizeof( netmessage_t ) );
163                 sock->msg.size = 0;
164                 return msg->size - 4;
165         } //end if
166           //the message has not been completely read yet
167 #if GDEF_DEBUG
168         printf( "++timo TODO: debug the Net_Receive on big size messages\n" );
169 #endif
170         return 0;
171 } //end of the function Net_Receive
172 //===========================================================================
173 //
174 // Parameter:                           -
175 // Returns:                                     -
176 // Changes Globals:             -
177 //===========================================================================
178 socket_t *Net_AllocSocket( void ){
179         socket_t *sock;
180
181         sock = (socket_t *) malloc( sizeof( socket_t ) );
182         memset( sock, 0, sizeof( socket_t ) );
183         return sock;
184 } //end of the function Net_AllocSocket
185 //===========================================================================
186 //
187 // Parameter:                           -
188 // Returns:                                     -
189 // Changes Globals:             -
190 //===========================================================================
191 void Net_FreeSocket( socket_t *sock ){
192         free( sock );
193 } //end of the function Net_FreeSocket
194 //===========================================================================
195 //
196 // Parameter:                           -
197 // Returns:                                     -
198 // Changes Globals:             -
199 //===========================================================================
200 socket_t *Net_Connect( address_t *address, int port ){
201         int newsock;
202         socket_t *sock;
203         sockaddr_t sendaddr;
204
205         // see if we can resolve the host name
206         WINS_StringToAddr( address->ip, &sendaddr );
207
208         newsock = WINS_OpenReliableSocket( port );
209         if ( newsock == -1 ) {
210                 return NULL;
211         }
212
213         sock = Net_AllocSocket();
214         if ( sock == NULL ) {
215                 WINS_CloseSocket( newsock );
216                 return NULL;
217         } //end if
218         sock->socket = newsock;
219
220         //connect to the host
221         if ( WINS_Connect( newsock, &sendaddr ) == -1 ) {
222                 Net_FreeSocket( sock );
223                 WINS_CloseSocket( newsock );
224                 WinPrint( "Net_Connect: error connecting\n" );
225                 return NULL;
226         } //end if
227
228         memcpy( &sock->addr, &sendaddr, sizeof( sockaddr_t ) );
229         //now we can send messages
230         //
231         return sock;
232 } //end of the function Net_Connect
233
234 //===========================================================================
235 //
236 // Parameter:                           -
237 // Returns:                                     -
238 // Changes Globals:             -
239 //===========================================================================
240 socket_t *Net_ListenSocket( int port ){
241         int newsock;
242         socket_t *sock;
243
244         newsock = WINS_OpenReliableSocket( port );
245         if ( newsock == -1 ) {
246                 return NULL;
247         }
248
249         if ( WINS_Listen( newsock ) == -1 ) {
250                 WINS_CloseSocket( newsock );
251                 return NULL;
252         } //end if
253         sock = Net_AllocSocket();
254         if ( sock == NULL ) {
255                 WINS_CloseSocket( newsock );
256                 return NULL;
257         } //end if
258         sock->socket = newsock;
259         WINS_GetSocketAddr( newsock, &sock->addr );
260         WinPrint( "listen socket opened at %s\n", WINS_AddrToString( &sock->addr ) );
261         //
262         return sock;
263 } //end of the function Net_ListenSocket
264 //===========================================================================
265 //
266 // Parameter:                           -
267 // Returns:                                     -
268 // Changes Globals:             -
269 //===========================================================================
270 socket_t *Net_Accept( socket_t *sock ){
271         int newsocket;
272         sockaddr_t sendaddr;
273         socket_t *newsock;
274
275         newsocket = WINS_Accept( sock->socket, &sendaddr );
276         if ( newsocket == -1 ) {
277                 return NULL;
278         }
279
280         newsock = Net_AllocSocket();
281         if ( newsock == NULL ) {
282                 WINS_CloseSocket( newsocket );
283                 return NULL;
284         } //end if
285         newsock->socket = newsocket;
286         memcpy( &newsock->addr, &sendaddr, sizeof( sockaddr_t ) );
287         //
288         return newsock;
289 } //end of the function Net_Accept
290 //===========================================================================
291 //
292 // Parameter:                           -
293 // Returns:                                     -
294 // Changes Globals:             -
295 //===========================================================================
296 void Net_Disconnect( socket_t *sock ){
297         WINS_CloseSocket( sock->socket );
298         Net_FreeSocket( sock );
299 } //end of the function Net_Disconnect
300 //===========================================================================
301 //
302 // Parameter:                           -
303 // Returns:                                     -
304 // Changes Globals:             -
305 //===========================================================================
306 void Net_StringToAddress( const char *string, address_t *address ){
307         strcpy( address->ip, string );
308 } //end of the function Net_StringToAddress
309 //===========================================================================
310 //
311 // Parameter:                           -
312 // Returns:                                     -
313 // Changes Globals:             -
314 //===========================================================================
315 void Net_MyAddress( address_t *address ){
316         strcpy( address->ip, WINS_MyAddress() );
317 } //end of the function Net_MyAddress
318 //===========================================================================
319 //
320 // Parameter:                           -
321 // Returns:                                     -
322 // Changes Globals:             -
323 //===========================================================================
324 int Net_Setup( void ){
325         WINS_Init();
326         //
327         WinPrint( "my address is %s\n", WINS_MyAddress() );
328         //
329         return qtrue;
330 } //end of the function Net_Setup
331 //===========================================================================
332 //
333 // Parameter:                           -
334 // Returns:                                     -
335 // Changes Globals:             -
336 //===========================================================================
337 void Net_Shutdown( void ){
338         WINS_Shutdown();
339 } //end of the function Net_Shutdown
340 //===========================================================================
341 //
342 // Parameter:                           -
343 // Returns:                                     -
344 // Changes Globals:             -
345 //===========================================================================
346 void NMSG_Clear( netmessage_t *msg ){
347         msg->size = 4;
348 } //end of the function NMSG_Clear
349 //===========================================================================
350 //
351 // Parameter:                           -
352 // Returns:                                     -
353 // Changes Globals:             -
354 //===========================================================================
355 void NMSG_WriteChar( netmessage_t *msg, int c ){
356         if ( c < -128 || c > 127 ) {
357                 WinPrint( "NMSG_WriteChar: range error\n" );
358         }
359
360         if ( msg->size >= MAX_NETMESSAGE ) {
361                 WinPrint( "NMSG_WriteChar: overflow\n" );
362                 return;
363         } //end if
364         msg->data[msg->size] = c;
365         msg->size++;
366 } //end of the function NMSG_WriteChar
367 //===========================================================================
368 //
369 // Parameter:                           -
370 // Returns:                                     -
371 // Changes Globals:             -
372 //===========================================================================
373 void NMSG_WriteByte( netmessage_t *msg, int c ){
374         if ( c < -128 || c > 127 ) {
375                 WinPrint( "NMSG_WriteByte: range error\n" );
376         }
377
378         if ( msg->size + 1 >= MAX_NETMESSAGE ) {
379                 WinPrint( "NMSG_WriteByte: overflow\n" );
380                 return;
381         } //end if
382         msg->data[msg->size] = c;
383         msg->size++;
384 } //end of the function NMSG_WriteByte
385 //===========================================================================
386 //
387 // Parameter:                           -
388 // Returns:                                     -
389 // Changes Globals:             -
390 //===========================================================================
391 void NMSG_WriteShort( netmessage_t *msg, int c ){
392         if ( c < ( (short)0x8000 ) || c > (short)0x7fff ) {
393                 WinPrint( "NMSG_WriteShort: range error" );
394         }
395
396         if ( msg->size + 2 >= MAX_NETMESSAGE ) {
397                 WinPrint( "NMSG_WriteShort: overflow\n" );
398                 return;
399         } //end if
400         msg->data[msg->size] = c & 0xff;
401         msg->data[msg->size + 1] = c >> 8;
402         msg->size += 2;
403 } //end of the function NMSG_WriteShort
404 //===========================================================================
405 //
406 // Parameter:                           -
407 // Returns:                                     -
408 // Changes Globals:             -
409 //===========================================================================
410 void NMSG_WriteLong( netmessage_t *msg, int c ){
411         if ( msg->size + 4 >= MAX_NETMESSAGE ) {
412                 WinPrint( "NMSG_WriteLong: overflow\n" );
413                 return;
414         } //end if
415         msg->data[msg->size] = c & 0xff;
416         msg->data[msg->size + 1] = ( c >> 8 ) & 0xff;
417         msg->data[msg->size + 2] = ( c >> 16 ) & 0xff;
418         msg->data[msg->size + 3] = c >> 24;
419         msg->size += 4;
420 } //end of the function NMSG_WriteLong
421 //===========================================================================
422 //
423 // Parameter:                           -
424 // Returns:                                     -
425 // Changes Globals:             -
426 //===========================================================================
427 void NMSG_WriteFloat( netmessage_t *msg, float c ){
428         if ( msg->size + 4 >= MAX_NETMESSAGE ) {
429                 WinPrint( "NMSG_WriteLong: overflow\n" );
430                 return;
431         } //end if
432         msg->data[msg->size] = *( (int *)&c ) & 0xff;
433         msg->data[msg->size + 1] = ( *( (int *)&c ) >> 8 ) & 0xff;
434         msg->data[msg->size + 2] = ( *( (int *)&c ) >> 16 ) & 0xff;
435         msg->data[msg->size + 3] = *( (int *)&c ) >> 24;
436         msg->size += 4;
437 } //end of the function NMSG_WriteFloat
438 //===========================================================================
439 //
440 // Parameter:                           -
441 // Returns:                                     -
442 // Changes Globals:             -
443 //===========================================================================
444 void NMSG_WriteString( netmessage_t *msg, char *string ){
445         if ( msg->size + strlen( string ) + 1 >= MAX_NETMESSAGE ) {
446                 WinPrint( "NMSG_WriteString: overflow\n" );
447                 return;
448         } //end if
449         memcpy( &msg->data[msg->size], string, strlen( string ) + 1 );
450         msg->size += strlen( string ) + 1;
451 } //end of the function NMSG_WriteString
452 //===========================================================================
453 //
454 // Parameter:                           -
455 // Returns:                                     -
456 // Changes Globals:             -
457 //===========================================================================
458 void NMSG_ReadStart( netmessage_t *msg ){
459         msg->readoverflow = qfalse;
460         msg->read = 4;
461 } //end of the function NMSG_ReadStart
462 //===========================================================================
463 //
464 // Parameter:                           -
465 // Returns:                                     -
466 // Changes Globals:             -
467 //===========================================================================
468 int NMSG_ReadChar( netmessage_t *msg ){
469         if ( msg->read + 1 > msg->size ) {
470                 msg->readoverflow = qtrue;
471                 WinPrint( "NMSG_ReadChar: read overflow\n" );
472                 return 0;
473         } //end if
474         msg->read++;
475         return msg->data[msg->read - 1];
476 } //end of the function NMSG_ReadChar
477 //===========================================================================
478 //
479 // Parameter:                           -
480 // Returns:                                     -
481 // Changes Globals:             -
482 //===========================================================================
483 int NMSG_ReadByte( netmessage_t *msg ){
484         if ( msg->read + 1 > msg->size ) {
485                 msg->readoverflow = qtrue;
486                 WinPrint( "NMSG_ReadByte: read overflow\n" );
487                 return 0;
488         } //end if
489         msg->read++;
490         return msg->data[msg->read - 1];
491 } //end of the function NMSG_ReadByte
492 //===========================================================================
493 //
494 // Parameter:                           -
495 // Returns:                                     -
496 // Changes Globals:             -
497 //===========================================================================
498 int NMSG_ReadShort( netmessage_t *msg ){
499         int c;
500
501         if ( msg->read + 2 > msg->size ) {
502                 msg->readoverflow = qtrue;
503                 WinPrint( "NMSG_ReadShort: read overflow\n" );
504                 return 0;
505         } //end if
506         c = (short)( msg->data[msg->read] + ( msg->data[msg->read + 1] << 8 ) );
507         msg->read += 2;
508         return c;
509 } //end of the function NMSG_ReadShort
510 //===========================================================================
511 //
512 // Parameter:                           -
513 // Returns:                                     -
514 // Changes Globals:             -
515 //===========================================================================
516 int NMSG_ReadLong( netmessage_t *msg ){
517         int c;
518
519         if ( msg->read + 4 > msg->size ) {
520                 msg->readoverflow = qtrue;
521                 WinPrint( "NMSG_ReadLong: read overflow\n" );
522                 return 0;
523         } //end if
524         c = msg->data[msg->read]
525                 + ( msg->data[msg->read + 1] << 8 )
526                 + ( msg->data[msg->read + 2] << 16 )
527                 + ( msg->data[msg->read + 3] << 24 );
528         msg->read += 4;
529         return c;
530 } //end of the function NMSG_ReadLong
531 //===========================================================================
532 //
533 // Parameter:                           -
534 // Returns:                                     -
535 // Changes Globals:             -
536 //===========================================================================
537 float NMSG_ReadFloat( netmessage_t *msg ){
538         int c;
539
540         if ( msg->read + 4 > msg->size ) {
541                 msg->readoverflow = qtrue;
542                 WinPrint( "NMSG_ReadLong: read overflow\n" );
543                 return 0;
544         } //end if
545         c = msg->data[msg->read]
546                 + ( msg->data[msg->read + 1] << 8 )
547                 + ( msg->data[msg->read + 2] << 16 )
548                 + ( msg->data[msg->read + 3] << 24 );
549         msg->read += 4;
550         return *(float *)&c;
551 } //end of the function NMSG_ReadFloat
552 //===========================================================================
553 //
554 // Parameter:                           -
555 // Returns:                                     -
556 // Changes Globals:             -
557 //===========================================================================
558 char *NMSG_ReadString( netmessage_t *msg ){
559         static char string[2048];
560         int l, c;
561
562         l = 0;
563         do
564         {
565                 if ( msg->read + 1 > msg->size ) {
566                         msg->readoverflow = qtrue;
567                         WinPrint( "NMSG_ReadString: read overflow\n" );
568                         string[l] = 0;
569                         return string;
570                 } //end if
571                 c = msg->data[msg->read];
572                 msg->read++;
573                 if ( c == 0 ) {
574                         break;
575                 }
576                 string[l] = c;
577                 l++;
578         } while ( (size_t) l < sizeof( string ) - 1 );
579         string[l] = 0;
580         return string;
581 } //end of the function NMSG_ReadString