]> Dogcows Code - chaz/thecheat/blob - CheatListener.m
The Cheat 1.0b4
[chaz/thecheat] / CheatListener.m
1
2 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 // Project: The Cheat
4 //
5 // File: CheatListener.m
6 // Created: Wed Sep 24 2003
7 //
8 // Copyright: 2003 Chaz McGarvey. All rights reserved.
9 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10
11 #import "CheatListener.h"
12
13 #import "CheatServer.h"
14
15 #include <string.h>
16
17
18 @implementation CheatListener
19
20
21 + (NSConnection *)listenerWithDelegate:(id)del port:(int)port remote:(BOOL)remote
22 {
23 NSPort *rPort = [NSPort port], *sPort = [NSPort port];
24 NSConnection *connection;
25 NSArray *array;
26
27 connection = [[NSConnection alloc] initWithReceivePort:rPort sendPort:sPort];
28 [connection setRootObject:del];
29
30 array = [NSArray arrayWithObjects:sPort, rPort, [NSNumber numberWithInt:port], [NSNumber numberWithBool:remote], nil];
31 [NSThread detachNewThreadSelector:@selector(listenerThread:) toTarget:self withObject:array];
32
33 return [connection autorelease];
34 }
35
36 + (void)listenerThread:(NSArray *)array
37 {
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]];
41
42 [object listenOnPort:[[array objectAtIndex:2] intValue] remote:[[array objectAtIndex:3] boolValue]];
43 [object run];
44 [object cleanup];
45
46 [object release];
47 [pool release];
48 }
49
50
51 - (id)initWithRootProxy:(id)proxy
52 {
53 if ( self = [super init] )
54 {
55 rootProxy = proxy;
56 sockfd = -1;
57 }
58
59 return self;
60 }
61
62
63 - (void)listenOnPort:(int)port remote:(BOOL)remote
64 {
65 short family = remote? AF_INET : AF_UNIX;
66
67 int yes = 1; // for setsockopt()
68
69 if ( (sockfd = socket( family, SOCK_STREAM, 0 )) == -1 )
70 {
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."];
73 return;
74 }
75
76 if ( family == AF_INET )
77 {
78 struct sockaddr_in addr;
79
80 addr.sin_family = family;
81 addr.sin_port = htonl( port );
82 addr.sin_addr.s_addr = INADDR_ANY;
83
84 if ( setsockopt( sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int) ) == -1 )
85 {
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."];
88 return;
89 }
90
91 if ( bind( sockfd, (struct sockaddr *)(&addr), sizeof(struct sockaddr) ) == -1 )
92 {
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."];
95 return;
96 }
97 }
98 else
99 {
100 struct sockaddr_un addr;
101
102 addr.sun_family = family;
103 strncpy( addr.sun_path, TCDefaultListenPath, 103 );
104
105 remove( TCDefaultListenPath );
106
107 if ( bind( sockfd, (struct sockaddr *)(&addr), sizeof(addr) ) == -1 )
108 {
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."];
111 return;
112 }
113 }
114
115 if ( listen( sockfd, 50 ) == -1 )
116 {
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."];
119 return;
120 }
121
122 listenRemote = remote;
123
124 [rootProxy listenerListeningWithSocket:sockfd];
125 }
126
127 - (void)run
128 {
129 int result;
130
131 NSLog( @"LISTENER start" );
132
133 if ( listenRemote )
134 {
135 struct sockaddr_in addr;
136 int addrLen;
137
138 for (;;)
139 {
140 addrLen = sizeof(addr);
141
142 if ( (result = accept( sockfd, (struct sockaddr *)(&addr), &addrLen )) == -1 )
143 {
144 break;
145 }
146
147 [rootProxy listenerReceivedNewConnection:result];
148 }
149 }
150 else
151 {
152 struct sockaddr_un addr;
153 int addrLen;
154
155 for (;;)
156 {
157 addrLen = sizeof(addr);
158
159 if ( (result = accept( sockfd, (struct sockaddr *)(&addr), &addrLen )) == -1 )
160 {
161 break;
162 }
163
164 [rootProxy listenerReceivedNewConnection:result];
165 }
166 }
167
168 NSLog( @"LISTENER close" );
169
170 [rootProxy listenerDisconnected];
171 }
172
173 - (void)cleanup
174 {
175 if ( listenRemote )
176 {
177 remove( TCDefaultListenPath );
178 }
179 }
180
181
182 @end
This page took 0.036303 seconds and 4 git commands to generate.