8 from xml
.dom
.minidom
import parse
, parseString
9 from threading
import Lock
16 PASSWORD
= "changethis"
23 SERVERREQUEST
= "i_want_server"
24 SERVEROFFER
= "Want_server?"
25 SERVERKILL
= "DIE_server!!"
26 YOUTHERE
= "you_there?"
27 IMHERE
= "yeah,i'm_here"
32 LIST
= "peoples_on_server"
33 SOMEONEJOINED
= "dude,someone_joined"
34 SOMEONELEFT
= "someone_left"
35 YOUROUT
= "get_lost_punk"
36 LETTER
= "listen_to_me"
44 def __init__(self
, config
):
51 self
.outgoing_lock
= Lock()
52 self
.incoming_lock
= Lock()
54 self
.broadcast
= socket(AF_INET
, SOCK_DGRAM
)
55 self
.message
= socket(AF_INET
, SOCK_DGRAM
)
59 self
.configuration
= config
61 if (config
.has_key('broadcast')):
62 self
.broadcast
.bind(('', config
['broadcast']))
64 print "Server.__init__(): No broadcast socket number chosen, using", BROADCAST
65 self
.broadcast
.bind(('', BROADCAST
))
67 if (config
.has_key('message')):
68 self
.message
.bind(('', config
['message']))
70 print "Server.__init__(): No message socket number chosen, using", MESSAGE
71 self
.message
.bind(('', MESSAGE
))
75 print "Server.receive() beginning..."
77 self
.message
.setblocking(1)
80 data_in
= self
.message
.recvfrom(BUFSIZE
)
82 self
.incoming_lock
.acquire()
83 self
.incoming
.append(data_in
)
84 print "Got data", data_in
85 self
.incoming_lock
.release()
91 print "Server.send() beginning..."
95 if (len(self
.outgoing
)):
97 self
.outgoing_lock
.acquire()
98 print "Server.send(): Acquired outgoing_lock"
100 data_out
= self
.outgoing
.pop(0)
102 self
.outgoing_lock
.release()
103 print "Server.send(): Released outgoing_lock"
105 self
.message
.sendto(data_out
[0], data_out
[1])
106 print "Server.send(): Sent data", data_out
109 def process_in(self
):
111 print "Server.process_in() beginning..."
113 while (self
.running
):
115 if (len(self
.incoming
)):
118 self
.incoming_lock
.acquire()
119 print "Server.process_in(): Acquired incoming_lock"
121 data_in
= self
.incoming
.pop(0)
123 self
.incoming_lock
.release()
124 print "Server.process_in(): Released incoming_lock"
126 if (data_in
[0][:len(WANTIN
)] == WANTIN
):
127 print "Server.process_in(): Received WANTIN"
129 response
= [YOUREIN
, data_in
[1]]
131 self
.outgoing_lock
.acquire()
132 print "Server.process_in(): Acquired outgoing_lock"
134 self
.outgoing
.append(response
)
136 self
.outgoing_lock
.release()
137 print "Server.process_in(): Released outgoing_lock"
139 self
.members
[data_in
[0][len(WANTIN
) + 1:]] = data_in
[1]
141 if (data_in
[0][:len(YOUTHERE
)] == YOUTHERE
):
142 print "Server.process_in(): Received YOUTHERE, responding with IMHERE"
144 response
= [IMHERE
, data_in
[1]]
146 self
.outgoing_lock
.acquire()
147 print "Server.process_in(): Acquired outgoing_lock"
149 self
.outgoing
.append(response
)
151 self
.outgoing_lock
.release()
152 print "Server.process_in(): Released outgoing_lock"
154 if (data_in
[0][:len(IMOUT
)] == IMOUT
):
155 print "Server.process_in(): Received IMOUT, notifying clients"
160 for name
, address
in self
.members
.iteritems():
161 if (data_in
[1] == address
):
162 response
[0] = SOMEONELEFT
+ " " + name
163 name_to_delete
= name
165 if (name_to_delete
!= ''):
166 del self
.members
[name_to_delete
]
168 for name
, address
in self
.members
.iteritems():
169 response
[1] = address
171 self
.outgoing_lock
.acquire()
172 print "Server.process_in(): Acquired outgoing_lock"
174 self
.outgoing
.append(response
)
176 self
.outgoing_lock
.release()
177 print "Server.process_in(): Released outgoing_lock"
179 if (data_in
[0] == GETLIST
):
180 print "Server.process_in(): Received GETLIST, responding with member list"
182 for name
, address
in self
.members
.iteritems():
183 if (address
== data_in
[1]):
186 response
[0] = LIST
+ " "
187 response
[1] = address
189 for iname
, iaddress
in self
.members
.iteritems():
191 response
[0] = response
[0] + iname
+ " "
193 self
.outgoing_lock
.acquire()
195 print "Server.process_in(): Acquired outgoing_lock"
197 self
.outgoing
.append(response
)
199 self
.outgoing_lock
.release()
200 print "Server.process_in(): Released outgoing_lock"
202 if (data_in
[0][:len(SERVERKILL
)] == SERVERKILL
):
203 print "Server.process_in(): Received SERVERKILL"
205 if (data_in
[0][len(SERVERKILL
) + 1:] == self
.configuration
['password']):
208 if (data_in
[0][:len(LETTER
)] == LETTER
):
209 print "Server.process_in(): Received LETTER"
213 the_data
= data_in
[0]
218 for name
in self
.members
.keys():
219 if self
.members
[name
] == data_in
[1]:
224 response
= [LETTER
+ ":" + origin
+ ":", []]
226 if the_data
[len(LETTER
):len(LETTER
)+2] == '::':
228 it_is
= the_data
[the_data
.find("::") + 2:]
231 for name
in self
.members
.keys():
235 responses
.append(response
)
236 responses
[-1][1] = self
.members
[name
]
240 it_is
= the_data
[the_data
.find(":", the_data
.find(":") + 1) + 1:]
243 string_parts
= the_data
[the_data
.find(":") + 1:
244 the_data
.find(":", the_data
.find(":") + 1)].split()
246 for dest
in string_parts
:
248 if self
.members
.has_key(dest
):
250 responses
.append(response
)
251 responses
[-1][1] = self
.members
[dest
]
253 for response_i
in responses
:
255 self
.outgoing_lock
.acquire()
256 self
.outgoing
.append(response_i
)
257 self
.outgoing_lock
.release()
261 def process_out(self
):
263 print "Server.process_out(): Not implemented yet."
267 def broadcast_listen(self
):
269 print "Listening on broadcast port:", self
.configuration
['broadcast']
271 broadcast_message
= SERVEROFFER
+ " " + str(self
.configuration
['message'])
272 broadcast_message
= broadcast_message
+ " " + self
.configuration
['name']
274 while (self
.running
):
275 data_in
= self
.broadcast
.recvfrom(BUFSIZE
)
277 if (data_in
[0][0:len(SERVERREQUEST
)] == SERVERREQUEST
):
278 new_message
= [broadcast_message
]
279 new_message
.append((data_in
[1][0], int(data_in
[0][len(SERVERREQUEST
) + 1:])))
281 self
.outgoing_lock
.acquire()
282 print "Server.broadcast_listen(): Acquired outgoing_lock"
284 self
.outgoing
.append(new_message
)
286 self
.outgoing_lock
.release()
287 print "Server.broadcast_listen(): Released outgoing_lock"
295 def parse_config(filename
):
297 parsed
= {'error': 1}
299 if (exists(filename
)):
300 dom
= parse(filename
)
302 print "parse_config():", filename
, "doesn't exist"
305 if (dom
.childNodes
[0].nodeName
== 'server_config'):
306 for node
in dom
.childNodes
[0].childNodes
:
308 if (node
.nodeName
== 'name' and len(node
.childNodes
)):
309 parsed
['name'] = node
.childNodes
[0].nodeValue
311 if (node
.nodeName
== 'password' and len(node
.childNodes
)):
312 parsed
['password'] = node
.childNodes
[0].nodeValue
314 if (node
.nodeName
== 'broadcast' and len(node
.childNodes
)):
315 parsed
['broadcast'] = int(node
.childNodes
[0].nodeValue
)
317 if (node
.nodeName
== 'message' and len(node
.childNodes
)):
318 parsed
['message'] = int(node
.childNodes
[0].nodeValue
)
324 def run(configuration
):
326 my_server
= Server(configuration
)
328 receive_thread
= threading
.Thread(target
=my_server
.receive
)
329 send_thread
= threading
.Thread(target
=my_server
.send
)
330 process_in_thread
= threading
.Thread(target
=my_server
.process_in
)
331 process_out_thread
= threading
.Thread(target
=my_server
.process_out
)
332 broadcast_thread
= threading
.Thread(target
=my_server
.broadcast_listen
)
334 receive_thread
.start()
337 process_in_thread
.start()
338 process_out_thread
.start()
339 broadcast_thread
.start()
341 receive_thread
.join()
343 broadcast_thread
.join()
344 process_in_thread
.join()
345 process_out_thread
.join()
349 def handler(signal
, frame
):
350 if (signal
== SIGINT
):
352 print "It should have ended"
356 # parsing command line options
358 if (len(sys
.argv
) > 1):
359 config_file
= sys
.argv
[1]
361 print "main(): No config file specified, using", CONFIG
364 parsed_config
= parse_config(config_file
)
366 if (parsed_config
['error']):
367 print "main(): Error parsing config, ending"
370 signal(SIGINT
, handler
)
374 if __name__
== '__main__':