| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | """socket.py for mac - Emulate socket module with mactcp and macdnr
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Currently only implements TCP sockets (AF_INET, SOCK_STREAM). | 
					
						
							|  |  |  | Esoteric things like socket options don't work, | 
					
						
							|  |  |  | but getpeername() and makefile() do work; everything used by ftplib works! | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Jack Jansen, CWI, November 1994 (initial version) | 
					
						
							|  |  |  | # Guido van Rossum, CWI, March 1995 (bug fixes and lay-out) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | import mactcp | 
					
						
							|  |  |  | import MACTCP | 
					
						
							|  |  |  | import macdnr | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Exported constants | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | _myerror = 'socket_wrapper.error' | 
					
						
							|  |  |  | error = (mactcp.error, macdnr.error, _myerror) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | SOCK_DGRAM = 1 | 
					
						
							|  |  |  | SOCK_STREAM = 2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AF_INET = 1 | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Internal constants | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-03-06 10:29:04 +00:00
										 |  |  | _BUFSIZE = 15*1024			# Size of TCP/UDP input buffer | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | _myaddress = None | 
					
						
							|  |  |  | _myname = None | 
					
						
							|  |  |  | _myaddrstr = None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def _myipaddress(): | 
					
						
							|  |  |  | 	global _myaddress | 
					
						
							|  |  |  | 	if _myaddress == None: | 
					
						
							|  |  |  | 		_myaddress = mactcp.IPAddr() | 
					
						
							|  |  |  | 	return _myaddress | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | def _ipaddress(str): | 
					
						
							|  |  |  | 	if type(str) == type(1): | 
					
						
							|  |  |  | 		return str			# Already numeric | 
					
						
							|  |  |  | 	ptr = macdnr.StrToAddr(str) | 
					
						
							|  |  |  | 	ptr.wait() | 
					
						
							|  |  |  | 	return ptr.ip0 | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | def gethostbyname(str): | 
					
						
							|  |  |  | 	id = _ipaddress(str) | 
					
						
							|  |  |  | 	return macdnr.AddrToStr(id) | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | def gethostname(): | 
					
						
							|  |  |  | 	global _myname | 
					
						
							|  |  |  | 	if _myname == None: | 
					
						
							|  |  |  | 		id = _myipaddress() | 
					
						
							|  |  |  | 		ptr = macdnr.AddrToName(id) | 
					
						
							|  |  |  | 		ptr.wait() | 
					
						
							|  |  |  | 		_myname = ptr.cname | 
					
						
							|  |  |  | 	return _myname | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | def _gethostaddress(): | 
					
						
							|  |  |  | 	global _myaddrstr | 
					
						
							|  |  |  | 	if _myaddrstr == None: | 
					
						
							|  |  |  | 		id = _myipaddress() | 
					
						
							|  |  |  | 		_myaddrstr = macdnr.AddrToStr(id) | 
					
						
							|  |  |  | 	return _myaddrstr | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | def socket(family, type, *which): | 
					
						
							|  |  |  | 	if family <> AF_INET: | 
					
						
							| 
									
										
										
										
											1995-03-06 10:29:04 +00:00
										 |  |  | 		raise _myerror, 'Protocol family %d not supported' % type | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | 	if type == SOCK_DGRAM: | 
					
						
							|  |  |  | 		return _udpsocket() | 
					
						
							|  |  |  | 	elif type == SOCK_STREAM: | 
					
						
							|  |  |  | 		return _tcpsocket() | 
					
						
							| 
									
										
										
										
											1995-03-06 10:29:04 +00:00
										 |  |  | 	raise _myerror, 'Protocol type %d not supported' % type | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | def fromfd(*args): | 
					
						
							| 
									
										
										
										
											1995-03-06 10:29:04 +00:00
										 |  |  | 	raise _myerror, 'Operation not supported on a mac' | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | class _socket: | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | 	def unsupported(self, *args): | 
					
						
							| 
									
										
										
										
											1995-03-06 10:29:04 +00:00
										 |  |  | 		raise _myerror, 'Operation not supported on this socket' | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	accept = unsupported | 
					
						
							|  |  |  | 	bind = unsupported | 
					
						
							|  |  |  | 	close = unsupported | 
					
						
							|  |  |  | 	connect = unsupported | 
					
						
							|  |  |  | 	fileno = unsupported | 
					
						
							|  |  |  | 	getpeername = unsupported | 
					
						
							|  |  |  | 	getsockname = unsupported | 
					
						
							|  |  |  | 	getsockopt = unsupported | 
					
						
							|  |  |  | 	listen = unsupported | 
					
						
							|  |  |  | 	recv = unsupported | 
					
						
							|  |  |  | 	recvfrom = unsupported | 
					
						
							|  |  |  | 	send = unsupported | 
					
						
							|  |  |  | 	sendto = unsupported | 
					
						
							|  |  |  | 	setblocking = unsupported | 
					
						
							|  |  |  | 	setsockopt = unsupported | 
					
						
							|  |  |  | 	shutdown = unsupported | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | class _tcpsocket(_socket): | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | 	def __init__(self): | 
					
						
							|  |  |  | 		self.stream = mactcp.TCPCreate(_BUFSIZE) | 
					
						
							|  |  |  | 		##self.stream.asr = self.asr | 
					
						
							|  |  |  | 		self.databuf = '' | 
					
						
							|  |  |  | 		self.udatabuf = '' | 
					
						
							|  |  |  | 		self.port = 0 | 
					
						
							|  |  |  | 		self.accepted = 0 | 
					
						
							|  |  |  | 		self.listening = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def accept(self): | 
					
						
							|  |  |  | 		if not self.listening: | 
					
						
							| 
									
										
										
										
											1995-03-06 10:29:04 +00:00
										 |  |  | 			raise _myerror, 'Not listening' | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | 		self.listening = 0 | 
					
						
							|  |  |  | 		self.stream.wait() | 
					
						
							|  |  |  | 		self.accepted = 1 | 
					
						
							|  |  |  | 		return self, self.getsockname() | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	# bind has two ways of calling: s.bind(host, port) or s.bind((host, port)); | 
					
						
							|  |  |  | 	# the latter is more proper but the former more common | 
					
						
							|  |  |  | 	def bind(self, a1, a2=None): | 
					
						
							|  |  |  | 		if a2 is None: | 
					
						
							|  |  |  | 			host, port = a1 | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			host, port = a1, a2 | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | 		self.port = port | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	def close(self): | 
					
						
							|  |  |  | 		if self.accepted: | 
					
						
							|  |  |  | 			self.accepted = 0 | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		self.stream.Abort() | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	# connect has the same problem as bind (see above) | 
					
						
							|  |  |  | 	def connect(self, a1, a2=None): | 
					
						
							|  |  |  | 		if a2 is None: | 
					
						
							|  |  |  | 			host, port = a1 | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			host, port = a1, a2 | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | 		self.stream.ActiveOpen(self.port, _ipaddress(host), port) | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	def getsockname(self): | 
					
						
							| 
									
										
										
										
											1995-01-19 11:49:05 +00:00
										 |  |  | 		host, port = self.stream.GetSockName() | 
					
						
							|  |  |  | 		host = macdnr.AddrToStr(host) | 
					
						
							|  |  |  | 		return host, port | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  | 	def getpeername(self): | 
					
						
							|  |  |  | 		st = self.stream.Status() | 
					
						
							|  |  |  | 		host = macdnr.AddrToStr(st.remoteHost) | 
					
						
							|  |  |  | 		return host, st.remotePort		 | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	def listen(self, backlog): | 
					
						
							|  |  |  | 		self.stream.PassiveOpen(self.port) | 
					
						
							|  |  |  | 		self.listening = 1 | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | 	def makefile(self, rw = 'r'): | 
					
						
							|  |  |  | 		return _socketfile(self, rw) | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  | 	def recv(self, bufsize, flags=0): | 
					
						
							|  |  |  | 		if flags: | 
					
						
							| 
									
										
										
										
											1995-03-06 10:29:04 +00:00
										 |  |  | 			raise _myerror, 'recv flags not yet supported on mac' | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | 		if not self.databuf: | 
					
						
							|  |  |  | 			try: | 
					
						
							|  |  |  | 				self.databuf, urg, mark = self.stream.Rcv(0) | 
					
						
							|  |  |  | 			except mactcp.error, arg: | 
					
						
							|  |  |  | 				if arg[0] != MACTCP.connectionClosing: | 
					
						
							|  |  |  | 					raise mactcp.error, arg | 
					
						
							|  |  |  | 		rv = self.databuf[:bufsize] | 
					
						
							|  |  |  | 		self.databuf = self.databuf[bufsize:] | 
					
						
							|  |  |  | 		return rv | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	def send(self, buf): | 
					
						
							|  |  |  | 		self.stream.Send(buf) | 
					
						
							|  |  |  | 		return len(buf) | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	def shutdown(self, how): | 
					
						
							|  |  |  | 		if how == 0: | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		self.stream.Close() | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	def bytes_readable(self): | 
					
						
							|  |  |  | 		st = self.stream.Status() | 
					
						
							|  |  |  | 		return st.amtUnreadData | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	def bytes_writeable(self): | 
					
						
							|  |  |  | 		st = self.stream.Status() | 
					
						
							|  |  |  | 		return st.sendWindow - st.sendUnacked; | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | class _udpsocket(_socket): | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | 	def __init__(self): | 
					
						
							|  |  |  | 		pass | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | class _socketfile: | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	def __init__(self, sock, rw): | 
					
						
							| 
									
										
										
										
											1995-03-06 10:29:04 +00:00
										 |  |  | 		if rw not in ('r', 'w'): raise _myerror, "mode must be 'r' or 'w'" | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | 		self.sock = sock | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | 		self.rw = rw | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | 		self.buf = '' | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | 	def read(self, length = 0): | 
					
						
							|  |  |  | 		if length <= 0: | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | 			length = 0x7fffffff | 
					
						
							|  |  |  | 		while len(self.buf) < length: | 
					
						
							|  |  |  | 			new = self.sock.recv(0x7fffffff) | 
					
						
							|  |  |  | 			if not new: | 
					
						
							|  |  |  | 				break | 
					
						
							|  |  |  | 			self.buf = self.buf + new | 
					
						
							|  |  |  | 		rv = self.buf[:length] | 
					
						
							|  |  |  | 		self.buf = self.buf[length:] | 
					
						
							|  |  |  | 		return rv | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	def readline(self): | 
					
						
							|  |  |  | 		import string | 
					
						
							|  |  |  | 		while not '\n' in self.buf: | 
					
						
							|  |  |  | 			new = self.sock.recv(0x7fffffff) | 
					
						
							|  |  |  | 			if not new: | 
					
						
							|  |  |  | 				break | 
					
						
							|  |  |  | 			self.buf = self.buf + new | 
					
						
							|  |  |  | 		if not '\n' in self.buf: | 
					
						
							|  |  |  | 			rv = self.buf | 
					
						
							|  |  |  | 			self.buf = '' | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			i = string.index(self.buf, '\n') | 
					
						
							|  |  |  | 			rv = self.buf[:i+1] | 
					
						
							|  |  |  | 			self.buf = self.buf[i+1:] | 
					
						
							|  |  |  | 		return rv | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | 	def write(self, buf): | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | 		BS = 512 | 
					
						
							|  |  |  | 		if len(buf) >= BS: | 
					
						
							|  |  |  | 			self.flush() | 
					
						
							|  |  |  | 			self.sock.send(buf) | 
					
						
							|  |  |  | 		elif len(buf) + len(self.buf) >= BS: | 
					
						
							|  |  |  | 			self.flush() | 
					
						
							|  |  |  | 			self.buf = buf | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			self.buf = self.buf + buf | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | 	def flush(self): | 
					
						
							|  |  |  | 		if self.buf and self.rw == 'w': | 
					
						
							|  |  |  | 			self.sock.send(self.buf) | 
					
						
							|  |  |  | 			self.buf = '' | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | 	def close(self): | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | 		self.flush() | 
					
						
							|  |  |  | 		##self.sock.close() | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | 		del self.sock | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | def __test_tcp(): | 
					
						
							|  |  |  | 	s = socket(AF_INET, SOCK_STREAM) | 
					
						
							|  |  |  | 	s.connect('poseidon.cwi.nl', 13) | 
					
						
							|  |  |  | 	rv = s.recv(1000) | 
					
						
							|  |  |  | 	print 'Time/date:', rv | 
					
						
							|  |  |  | 	rv = s.recv(1000) | 
					
						
							|  |  |  | 	if rv: | 
					
						
							|  |  |  | 		print 'Unexpected extra data:', rv | 
					
						
							|  |  |  | 	s.close() | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											1995-03-04 22:24:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-12-14 13:06:25 +00:00
										 |  |  | def __test_udp(): | 
					
						
							|  |  |  | 	s = socket(AF_INET, SOCK_DGRAM) | 
					
						
							|  |  |  | 	print 'Sending data... (hello world)' | 
					
						
							|  |  |  | 	s.sendto(('poseidon.cwi.nl', 7), 'hello world') | 
					
						
							|  |  |  | 	rv, host = s.recvfrom(1000) | 
					
						
							|  |  |  | 	print 'Got from ', host, ':', rv |