2 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 // File: CheatListener.m
6 // Created: Wed Sep 24 2003
8 // Copyright: 2003 Chaz McGarvey. All rights reserved.
9 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11 #import "CheatListener.h"
13 #import "CheatServer.h"
18 @implementation CheatListener
21 + (NSConnection
*)listenerWithDelegate
:(id)del port
:(int)port remote
:(BOOL)remote
23 NSPort
*rPort
= [NSPort port
], *sPort
= [NSPort port
];
24 NSConnection
*connection
;
27 connection
= [[NSConnection alloc
] initWithReceivePort
:rPort sendPort
:sPort
];
28 [connection setRootObject
:del
];
30 array
= [NSArray arrayWithObjects
:sPort
, rPort
, [NSNumber numberWithInt
:port
], [NSNumber numberWithBool
:remote
], nil];
31 [NSThread detachNewThreadSelector
:@selector(listenerThread
:) toTarget
:self withObject
:array
];
33 return [connection autorelease
];
36 + (void)listenerThread
:(NSArray
*)array
38 NSAutoreleasePool
*pool
= [[NSAutoreleasePool alloc
] init
];
39 NSConnection
*connection
= [NSConnection connectionWithReceivePort
:[array objectAtIndex
:0] sendPort
:[array objectAtIndex
:1]];
40 CheatListener
*object
= [[self alloc
] initWithRootProxy
:[connection rootProxy
]];
42 [object listenOnPort
:[[array objectAtIndex
:2] intValue
] remote
:[[array objectAtIndex
:3] boolValue
]];
51 - (id)initWithRootProxy
:(id)proxy
53 if ( self = [super init
] )
63 - (void)listenOnPort
:(int)port remote
:(BOOL)remote
65 short family
= remote? AF_INET
: AF_UNIX
;
67 int yes
= 1; // for setsockopt()
69 if ( (sockfd
= socket( family
, SOCK_STREAM
, 0 )) == -1 )
71 NSLog( @
"ERROR: failed to start server because socket() failed" );
72 [rootProxy listenerError
:@
"Network Error" message
:@
"Server couldn't start. Local can't be cheated."];
76 if ( family
== AF_INET
)
78 struct sockaddr_in addr
;
80 addr.sin_family
= family
;
81 addr.sin_port
= htonl( port
);
82 addr.sin_addr.s_addr
= INADDR_ANY
;
84 if ( setsockopt( sockfd
, SOL_SOCKET
, SO_REUSEADDR
, &yes
, sizeof(int) ) == -1 )
86 NSLog( @
"ERROR: failed to start server because setsockopt() failed" );
87 [rootProxy listenerError
:@
"Network Error" message
:@
"Server couldn't start. Local can't be cheated."];
91 if ( bind( sockfd
, (struct sockaddr
*)(&addr
), sizeof(struct sockaddr
) ) == -1 )
93 NSLog( @
"ERROR: failed to start server because bind() failed" );
94 [rootProxy listenerError
:@
"Network Error" message
:@
"The cheat server could not start, probably because the port is already in use. Local can not be cheated."];
100 struct sockaddr_un addr
;
102 addr.sun_family
= family
;
103 strncpy( addr.sun_path
, TCDefaultListenPath
, 103 );
105 remove( TCDefaultListenPath
);
107 if ( bind( sockfd
, (struct sockaddr
*)(&addr
), sizeof(addr
) ) == -1 )
109 NSLog( @
"ERROR: failed to start server because bind() failed" );
110 [rootProxy listenerError
:@
"Network Error" message
:@
"The cheat server could not start, probably because the path is already in use. Local can not be cheated."];
115 if ( listen( sockfd
, 50 ) == -1 )
117 NSLog( @
"ERROR: failed to start server because listen() failed" );
118 [rootProxy listenerError
:@
"Network Error" message
:@
"Server couldn't start. Local can't be cheated."];
122 listenRemote
= remote
;
124 [rootProxy listenerListeningWithSocket
:sockfd
];
131 NSLog( @
"LISTENER start" );
135 struct sockaddr_in addr
;
140 addrLen
= sizeof(addr
);
142 if ( (result
= accept( sockfd
, (struct sockaddr
*)(&addr
), &addrLen
)) == -1 )
147 [rootProxy listenerReceivedNewConnection
:result
];
152 struct sockaddr_un addr
;
157 addrLen
= sizeof(addr
);
159 if ( (result
= accept( sockfd
, (struct sockaddr
*)(&addr
), &addrLen
)) == -1 )
164 [rootProxy listenerReceivedNewConnection
:result
];
168 NSLog( @
"LISTENER close" );
170 [rootProxy listenerDisconnected
];
177 remove( TCDefaultListenPath
);