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