home *** CD-ROM | disk | FTP | other *** search
- """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)
-
-
- import mactcp
- import MACTCPconst
- import macdnr
-
-
- # Exported constants
-
- _myerror = 'socket_wrapper.error'
- error = (mactcp.error, macdnr.error, _myerror)
-
- SOCK_DGRAM = 1
- SOCK_STREAM = 2
-
- AF_INET = 1
-
-
- # Internal constants
-
- _BUFSIZE = 15*1024 # Size of TCP/UDP input buffer
-
- _myaddress = None
- _myname = None
- _myaddrstr = None
-
-
- def _myipaddress():
- global _myaddress
- if _myaddress == None:
- _myaddress = mactcp.IPAddr()
- return _myaddress
-
-
- def _ipaddress(str):
- if type(str) == type(1):
- return str # Already numeric
- ptr = macdnr.StrToAddr(str)
- ptr.wait()
- return ptr.ip0
-
-
- def gethostbyname(str):
- id = _ipaddress(str)
- return macdnr.AddrToStr(id)
-
-
- def gethostbyaddr(str):
- id = _ipaddress(str)
- ptr = macdnr.AddrToName(id)
- ptr.wait()
- name = ptr.cname
- if name[-1:] == '.': name = name[:-1]
- names, addresses = [], [str]
- return name, names, addresses
-
- def gethostname():
- global _myname
- if _myname == None:
- id = _myipaddress()
- ptr = macdnr.AddrToName(id)
- ptr.wait()
- _myname = ptr.cname
- return _myname
-
-
- def _gethostaddress():
- global _myaddrstr
- if _myaddrstr == None:
- id = _myipaddress()
- _myaddrstr = macdnr.AddrToStr(id)
- return _myaddrstr
-
-
- def socket(family, type, *which):
- if family <> AF_INET:
- raise _myerror, 'Protocol family %d not supported' % type
- if type == SOCK_DGRAM:
- return _udpsocket()
- elif type == SOCK_STREAM:
- return _tcpsocket()
- raise _myerror, 'Protocol type %d not supported' % type
-
-
- def fromfd(*args):
- raise _myerror, 'Operation not supported on a mac'
-
-
- class _socket:
- def unsupported(self, *args):
- raise _myerror, 'Operation not supported on this socket'
-
- 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
-
-
- class _tcpsocket(_socket):
-
- 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:
- raise _myerror, 'Not listening'
- self.listening = 0
- self.stream.wait()
- self.accepted = 1
- return self, self.getsockname()
-
- # 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
- self.port = port
-
- def close(self):
- if self.accepted:
- self.accepted = 0
- return
- self.stream.Abort()
-
- # 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
- self.stream.ActiveOpen(self.port, _ipaddress(host), port)
-
- def getsockname(self):
- host, port = self.stream.GetSockName()
- host = macdnr.AddrToStr(host)
- return host, port
-
- 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
-
- def makefile(self, rw = 'r', bs = 512):
- return _socketfile(self, rw, bs)
-
- def recv(self, bufsize, flags=0):
- if flags:
- raise _myerror, 'recv flags not yet supported on mac'
- if not self.databuf:
- try:
- self.databuf, urg, mark = self.stream.Rcv(0)
- except mactcp.error, arg:
- if arg[0] != MACTCPconst.connectionClosing:
- raise mactcp.error, arg
- rv = self.databuf[:bufsize]
- self.databuf = self.databuf[bu