📄 mpdlib.py
字号:
return (1,(msg['rhsifhn'],msg['rhsport'])) else: return (1,None) def connect_rhs(self,rhsIfhn='',rhsPort=0,rhsHandler=None,numTries=1): if not rhsHandler: mpd_print(1, "must supply handler for rhs in ring") return (-1,None) if not rhsIfhn: mpd_print(1, "must supply host for rhs in ring") return (-1,None) self.rhsIfhn = rhsIfhn if not rhsPort: mpd_print(1, "must supply port for rhs in ring") return (-1,None) self.rhsPort = rhsPort numConnTries = 0 while numConnTries < numTries: numConnTries += 1 self.rhsSock = MPDSock(name='rhs') try: self.rhsSock.connect((self.rhsIfhn,self.rhsPort)) except socket.error, errinfo: print '%s: conn error in connect_rhs: %s' % \ (mpd_my_id,os.strerror(errinfo[0])) self.rhsSock.close() self.rhsSock = 0 sleep(random()) continue break if not self.rhsSock or numConnTries > numTries: mpd_print(1,'failed to connect to rhs at %s %d' % (self.rhsIfhn,self.rhsPort)) return (0,None) msgToSend = { 'cmd' : 'request_to_enter_as_lhs', 'ifhn' : self.myIfhn, 'port' : self.listenPort, 'mpd_version' : mpd_version() } self.rhsSock.send_dict_msg(msgToSend) msg = self.rhsSock.recv_dict_msg() if (not msg) \ or (not msg.has_key('cmd')) \ or (not msg['cmd'] == 'challenge') \ or (not msg.has_key('randnum')) \ or (not msg.has_key('generation')): mpd_print(1,'invalid challenge from %s %d: %s' % (self.rhsIfhn,rhsPort,msg) ) return (-1,None) if msg['generation'] < self.generation: mpd_print(1,'bad generation from rhs; lhsgen=%d mygen=%d' % (msg['generation'],self.generation)) return(-1,'bad_generation') # RMB: try again here later response = md5new(''.join([self.secretword,msg['randnum']])).digest() msgToSend = { 'cmd' : 'challenge_response', 'response' : response, 'ifhn' : self.myIfhn, 'port' : self.listenPort } self.rhsSock.send_dict_msg(msgToSend) msg = self.rhsSock.recv_dict_msg() if (not msg) \ or (not msg.has_key('cmd')) \ or (not msg['cmd'] == 'OK_to_enter_as_lhs'): mpd_print(1,'NOT OK to enter ring; one likely cause: mismatched secretwords') return (-1,None) self.rhsHandler = rhsHandler self.streamHandler.set_handler(self.rhsSock,rhsHandler) if msg.has_key('lhsifhn') and msg.has_key('lhsport'): return (1,(msg['lhsifhn'],msg['lhsport'])) else: return (1,None) def accept_lhs(self,lhsHandler=None): self.lhsHandler = lhsHandler newsock = self.handle_ring_listener_connection(self.listenSock) self.handle_lhs_challenge_response(newsock) self.streamHandler.set_handler(self.lhsSock,lhsHandler) def accept_rhs(self,rhsHandler=None): self.rhsHandler = rhsHandler newsock = self.handle_ring_listener_connection(self.listenSock) self.handle_rhs_challenge_response(newsock) self.streamHandler.set_handler(self.rhsSock,rhsHandler) def handle_ring_listener_connection(self,sock): randHiRange = 10000 (newsock,newaddr) = sock.accept() newsock.name = 'candidate_to_enter_ring' msg = newsock.recv_dict_msg() if (not msg) or \ (not msg.has_key('cmd')) or (not msg.has_key('ifhn')) or \ (not msg.has_key('port')): mpd_print(1, 'INVALID msg from new connection :%s: msg=:%s:' % (newaddr,msg) ) newsock.close() return None if msg.has_key('mpd_version'): # ping, etc may not have one if msg['mpd_version'] != mpd_version(): msgToSend = { 'cmd' : 'entry_rejected_bad_mpd_version', 'your_version' : msg['mpd_version'], 'my_version' : mpd_version() } newsock.send_dict_msg(msgToSend) newsock.close() return None randNumStr = '%04d' % (randrange(1,randHiRange)) # 0001-(hi-1), inclusive newsock.correctChallengeResponse = \ md5new(''.join([self.secretword,randNumStr])).digest() msgToSend = { 'cmd' : 'challenge', 'randnum' : randNumStr, 'generation' : self.generation } newsock.send_dict_msg(msgToSend) if msg['cmd'] == 'request_to_enter_as_lhs': self.streamHandler.set_handler(newsock,self.handle_lhs_challenge_response) newsock.name = 'candidate_for_lhs_challenged' return newsock elif msg['cmd'] == 'request_to_enter_as_rhs': self.streamHandler.set_handler(newsock,self.handle_rhs_challenge_response) newsock.name = 'candidate_for_rhs_challenged' return newsock elif msg['cmd'] == 'ping': # already sent challenge instead of ack newsock.close() return None else: mpd_print(1, 'INVALID msg from new connection :%s: msg=:%s:' % (newaddr,msg) ) newsock.close() return None return None def handle_lhs_challenge_response(self,sock): msg = sock.recv_dict_msg() if (not msg) or \ (not msg.has_key('cmd')) or (not msg.has_key('response')) or \ (not msg.has_key('ifhn')) or (not msg.has_key('port')) or \ (not msg['response'] == sock.correctChallengeResponse): mpd_print(1, 'INVALID msg for lhs response msg=:%s:' % (msg) ) msgToSend = { 'cmd' : 'invalid_response' } sock.send_dict_msg(msgToSend) self.streamHandler.del_handler(sock) sock.close() else: msgToSend = { 'cmd' : 'OK_to_enter_as_lhs' } sock.send_dict_msg(msgToSend) if self.lhsSock: self.streamHandler.del_handler(self.lhsSock) self.lhsSock.close() self.lhsSock = sock self.lhsIfhn = msg['ifhn'] self.lhsPort = int(msg['port']) self.streamHandler.set_handler(self.lhsSock,self.lhsHandler) self.lhsSock.name = 'lhs' def handle_rhs_challenge_response(self,sock): msg = sock.recv_dict_msg() if (not msg) or \ (not msg.has_key('cmd')) or (not msg.has_key('response')) or \ (not msg.has_key('ifhn')) or (not msg.has_key('port')): mpd_print(1, 'INVALID msg for rhs response msg=:%s:' % (msg) ) msgToSend = { 'cmd' : 'invalid_response' } sock.send_dict_msg(msgToSend) self.streamHandler.del_handler(sock) sock.close() elif msg['response'] != sock.correctChallengeResponse: mpd_print(1, 'INVALID response in rhs response msg=:%s:' % (msg) ) msgToSend = { 'cmd' : 'invalid_response' } sock.send_dict_msg(msgToSend) self.streamHandler.del_handler(sock) sock.close() elif msg['response'] == 'bad_generation': mpd_print(1, 'someone failed entering my ring gen=%d msg=%s' % \ (self.generation,msg) ) self.streamHandler.del_handler(sock) sock.close() else: msgToSend = { 'cmd' : 'OK_to_enter_as_rhs', 'rhsifhn' : self.rhsIfhn, 'rhsip' : self.rhsIfhn, 'rhsport' : self.rhsPort } sock.send_dict_msg(msgToSend) if self.rhsSock: self.streamHandler.del_handler(self.rhsSock) self.rhsSock.close() self.rhsSock = sock self.rhsIfhn = msg['ifhn'] self.rhsPort = int(msg['port']) self.streamHandler.set_handler(self.rhsSock,self.rhsHandler) self.rhsSock.name = 'rhs'class MPDConListenSock(MPDListenSock): def __init__(self,name='console_listen',secretword='',**kargs): if os.environ.has_key('MPD_CON_EXT'): self.conExt = '_' + os.environ['MPD_CON_EXT'] else: self.conExt = '' self.conFilename = '/tmp/mpd2.console_' + mpd_get_my_username() + self.conExt self.secretword = secretword consoleAlreadyExists = 0 if hasattr(socket,'AF_UNIX'): sockFamily = socket.AF_UNIX else: sockFamily = socket.AF_INET if os.environ.has_key('MPD_CON_INET_HOST_PORT'): sockFamily = socket.AF_INET # override above-assigned value (conHost,conPort) = os.environ['MPD_CON_INET_HOST_PORT'].split(':') conPort = int(conPort) else: (conHost,conPort) = ('',0) if os.access(self.conFilename,os.R_OK): # if console there, see if mpd listening if hasattr(socket,'AF_UNIX') and sockFamily == socket.AF_UNIX: tempSock = MPDSock(family=socket.AF_UNIX) try: tempSock.connect(self.conFilename) consoleAlreadyExists = 1 except Exception, errmsg: os.unlink(self.conFilename) tempSock.close() else: if not conPort: conFile = open(self.conFilename) for line in conFile: line = line.strip() (k,v) = line.split('=') if k == 'port': conPort = int(v) conFile.close() tempSock = MPDSock() try: tempSock.sock.connect(('localhost',conPort)) consoleAlreadyExists = 1 except Exception, errmsg: os.unlink(self.conFilename) tempSock.close() if consoleAlreadyExists: print 'An mpd is already running with console at %s on %s. ' % \ (self.conFilename, socket.gethostname()) print 'Start mpd with the -n option for a second mpd on same host.' if syslog_module_available: syslog.syslog(syslog.LOG_ERR, "%s: exiting; an mpd is already using the console" % \ (mpd_my_id)) sys.exit(-1) if hasattr(socket,'AF_UNIX') and sockFamily == socket.AF_UNIX: MPDListenSock.__init__(self,family=sockFamily,socktype=socket.SOCK_STREAM, filename=self.conFilename,listen=1,name=name) else: MPDListenSock.__init__(self,family=sockFamily,socktype=socket.SOCK_STREAM, port=conPort,listen=1,name=name) conFD = os.open(self.conFilename,os.O_CREAT|os.O_WRONLY|os.O_EXCL,0600) self.port = self.sock.getsockname()[1] os.write(conFD,'port=%d\n' % (self.port) ) os.close(conFD)class MPDConClientSock(MPDSock): def __init__(self,name='console_to_mpd',mpdroot='',secretword='',**kargs): MPDSock.__init__(self) self.sock = 0 if os.environ.has_key('MPD_CON_EXT'): self.conExt = '_' + os.environ['MPD_CON_EXT'] else: self.conExt = '' self.secretword = secretword if mpdroot: self.conFilename = '/tmp/mpd2.console_root' + self.conExt self.sock = MPDSock(family=socket.AF_UNIX,name=name) rootpid = os.fork() if rootpid == 0: os.execvpe(mpdroot,[mpdroot,self.conFilename,str(self.sock.fileno())],{}) mpd_print(1,'failed to exec mpdroot (%s)' % mpdroot ) sys.exit(-1) else: (pid,status) = os.waitpid(rootpid,0) if os.WIFSIGNALED(status): status = status & 0x007f # AND off core flag else: status = os.WEXITSTATUS(status) if status != 0: mpd_print(1,'forked process failed; status=%s' % status) sys.exit(-1) else: self.conFilename = '/tmp/mpd2.console_' + mpd_get_my_username() + self.conExt if hasattr(socket,'AF_UNIX'): sockFamily = socket.AF_UNIX else: sockFamily = socket.AF_INET if os.environ.has_key('MPD_CON_INET_HOST_PORT'): sockFamily = socket.AF_INET # override above-assigned value (conHost,conPort) = os.environ['MPD_CON_INET_HOST_PORT'].split(':') conPort = int(conPort) else: (conHost,conPort) = ('',0) self.sock = MPDSock(family=sockFamily,socktype=socket.SOCK_STREAM,name=name) if hasattr(socket,'AF_UNIX') and sockFamily == socket.AF_UNIX: if hasattr(signal,'alarm'): oldAlarmTime = signal.alarm(8) else: # assume python2.3 or later oldTimeout = socket.getdefaulttimeout() socket.setdefaulttimeout(8) try: self.sock.connect(self.conFilename) except Exception, errmsg: self.sock.close() self.sock = 0 if hasattr(signal,'alarm'): signal.alarm(oldAlarmTime) else: # assume python2.3 or later socket.setdefaulttimeout(oldTimeout) if self.sock: # this is done by mpdroot otherwise msgToSend = 'realusername=%s secretword=UNUSED\n' % \ mpd_get_my_username() self.sock.send_char_msg(msgToSend) else: if not conPort: conFile = open(self.conFilename) for line in conFile: line = line.strip() (k,v) = line.split('=') if k == 'port': conPort = int(v) conFile.close() if conHost: conIfhn = socket.gethostbyname_ex(conHost)[2][0] else: conIfhn = 'localhost' self.sock = MPDSock(name=name) if hasattr(signal,'alarm'): oldAlarmTime = signal.alarm(8)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -