diff options
-rw-r--r-- | Demo/rpc/MANIFEST | 1 | ||||
-rw-r--r-- | Demo/rpc/README | 10 | ||||
-rw-r--r-- | Demo/rpc/mountclient.py | 18 | ||||
-rw-r--r-- | Demo/rpc/nfsclient.py | 12 | ||||
-rw-r--r-- | Demo/rpc/rnusersclient.py | 16 | ||||
-rw-r--r-- | Demo/rpc/rpc.py | 105 | ||||
-rwxr-xr-x | Demo/rpc/test | 1 | ||||
-rw-r--r-- | Demo/rpc/xdr.py | 39 |
8 files changed, 123 insertions, 79 deletions
diff --git a/Demo/rpc/MANIFEST b/Demo/rpc/MANIFEST index 0a91f13..e65f3eb 100644 --- a/Demo/rpc/MANIFEST +++ b/Demo/rpc/MANIFEST @@ -6,4 +6,5 @@ mountclient.py 1 nfsclient.py 1 rpc.py 1 + test 1 xdr.py 1 diff --git a/Demo/rpc/README b/Demo/rpc/README index 4e00e05..be75c10 100644 --- a/Demo/rpc/README +++ b/Demo/rpc/README @@ -21,13 +21,3 @@ Other clients are tested similarly. For hostname, use e.g. wuarchive.wustl.edu or gatekeeper.dec.com (two hosts that are known to export NFS filesystems with little restrictions). - -Note: this was developed using Python 0.9.8beta (not yet released). I -have tried to put in compatibility hacks for Python 0.9.7beta -(available from ftp.cwi.nl) but I cannot guarantee that it will work --- if it doesn't, let me know and I'll see what I can do. In -particular, if you don't have the built-in module "select", UDP -time-outs and retries won't work. - ---Guido van Rossum, CWI, Amsterdam <guido@cwi.nl> -"I don't want *any* spam" diff --git a/Demo/rpc/mountclient.py b/Demo/rpc/mountclient.py index fde6f4d..ff66b3d 100644 --- a/Demo/rpc/mountclient.py +++ b/Demo/rpc/mountclient.py @@ -74,13 +74,13 @@ class MountUnpacker(Unpacker): class PartialMountClient: - # This method is called by Client.init to initialize + # This method is called by Client.__init__ to initialize # self.packer and self.unpacker def addpackers(self): - self.packer = MountPacker().init() - self.unpacker = MountUnpacker().init('') + self.packer = MountPacker() + self.unpacker = MountUnpacker('') - # This method is called by Client.init to bind the socket + # This method is called by Client.__init__ to bind the socket # to a particular network interface and port. We use the # default network interface, but if we're running as root, # we want to bind to a reserved port @@ -161,14 +161,14 @@ class PartialMountClient: class TCPMountClient(PartialMountClient, TCPClient): - def init(self, host): - return TCPClient.init(self, host, MOUNTPROG, MOUNTVERS) + def __init__(self, host): + TCPClient.__init__(self, host, MOUNTPROG, MOUNTVERS) class UDPMountClient(PartialMountClient, UDPClient): - def init(self, host): - return UDPClient.init(self, host, MOUNTPROG, MOUNTVERS) + def __init__(self, host): + UDPClient.__init__(self, host, MOUNTPROG, MOUNTVERS) # A little test program for the Mount client. This takes a host as @@ -189,7 +189,7 @@ def test(): C = UDPMountClient if sys.argv[1:]: host = sys.argv[1] else: host = '' - mcl = C().init(host) + mcl = C(host) list = mcl.Export() for item in list: print item diff --git a/Demo/rpc/nfsclient.py b/Demo/rpc/nfsclient.py index 467e495..498e2d0 100644 --- a/Demo/rpc/nfsclient.py +++ b/Demo/rpc/nfsclient.py @@ -121,12 +121,12 @@ class NFSUnpacker(MountUnpacker): class NFSClient(UDPClient): - def init(self, host): - return UDPClient.init(self, host, NFS_PROGRAM, NFS_VERSION) + def __init__(self, host): + UDPClient.__init__(self, host, NFS_PROGRAM, NFS_VERSION) def addpackers(self): - self.packer = NFSPacker().init() - self.unpacker = NFSUnpacker().init('') + self.packer = NFSPacker() + self.unpacker = NFSUnpacker('') def mkcred(self): if self.cred == None: @@ -183,7 +183,7 @@ def test(): if sys.argv[2:]: filesys = sys.argv[2] else: filesys = None from mountclient import UDPMountClient, TCPMountClient - mcl = TCPMountClient().init(host) + mcl = TCPMountClient(host) if filesys == None: list = mcl.Export() for item in list: @@ -193,7 +193,7 @@ def test(): print sf fh = sf[1] if fh: - ncl = NFSClient().init(host) + ncl = NFSClient(host) as = ncl.Getattr(fh) print as list = ncl.Listdir(fh) diff --git a/Demo/rpc/rnusersclient.py b/Demo/rpc/rnusersclient.py index 4d540f8..e9cad62 100644 --- a/Demo/rpc/rnusersclient.py +++ b/Demo/rpc/rnusersclient.py @@ -37,8 +37,8 @@ class RnusersUnpacker(Unpacker): class PartialRnusersClient: def addpackers(self): - self.packer = RnusersPacker().init() - self.unpacker = RnusersUnpacker().init('') + self.packer = RnusersPacker() + self.unpacker = RnusersUnpacker('') def Num(self): return self.make_call(1, None, None, self.unpacker.unpack_int) @@ -54,14 +54,14 @@ class PartialRnusersClient: class RnusersClient(PartialRnusersClient, UDPClient): - def init(self, host): - return UDPClient.init(self, host, 100002, 2) + def __init__(self, host): + UDPClient.__init__(self, host, 100002, 2) class BroadcastRnusersClient(PartialRnusersClient, BroadcastUDPClient): - def init(self, bcastaddr): - return BroadcastUDPClient.init(self, bcastaddr, 100002, 2) + def __init__(self, bcastaddr): + BroadcastUDPClient.__init__(self, bcastaddr, 100002, 2) def test(): @@ -71,7 +71,7 @@ def test(): return else: host = sys.argv[1] - c = RnusersClient().init(host) + c = RnusersClient(host) list = c.Names() for (line, name, host, time), idle in list: line = strip0(line) @@ -80,7 +80,7 @@ def test(): print `name`, `host`, `line`, time, idle def testbcast(): - c = BroadcastRnusersClient().init('<broadcast>') + c = BroadcastRnusersClient('<broadcast>') def listit(list, fromaddr): host, port = fromaddr print host + '\t:', diff --git a/Demo/rpc/rpc.py b/Demo/rpc/rpc.py index 00397dd..fb21fc2 100644 --- a/Demo/rpc/rpc.py +++ b/Demo/rpc/rpc.py @@ -151,7 +151,7 @@ def make_auth_null(): return '' def make_auth_unix(seed, host, uid, gid, groups): - p = Packer().init() + p = Packer() p.pack_auth_unix(seed, host, uid, gid, groups) return p.get_buf() @@ -163,14 +163,15 @@ def make_auth_unix_default(): except ImportError: uid = gid = 0 import time - return make_auth_unix(time.time(), socket.gethostname(), uid, gid, []) + return make_auth_unix(int(time.time()), \ + socket.gethostname(), uid, gid, []) # Common base class for clients class Client: - def init(self, host, prog, vers, port): + def __init__(self, host, prog, vers, port): self.host = host self.prog = prog self.vers = vers @@ -182,7 +183,6 @@ class Client: self.addpackers() self.cred = None self.verf = None - return self def close(self): self.sock.close() @@ -201,8 +201,8 @@ class Client: def addpackers(self): # Override this to use derived classes from Packer/Unpacker - self.packer = Packer().init() - self.unpacker = Unpacker().init('') + self.packer = Packer() + self.unpacker = Unpacker('') def make_call(self, proc, args, pack_func, unpack_func): # Don't normally override this (but see Broadcast) @@ -244,7 +244,7 @@ class Client: self.verf = (AUTH_NULL, make_auth_null()) return self.verf - def Null(self): # Procedure 0 is always like this + def call_0(self): # Procedure 0 is always like this return self.make_call(0, None, None, None) @@ -369,11 +369,10 @@ class RawUDPClient(Client): class RawBroadcastUDPClient(RawUDPClient): - def init(self, bcastaddr, prog, vers, port): - self = RawUDPClient.init(self, bcastaddr, prog, vers, port) + def __init__(self, bcastaddr, prog, vers, port): + RawUDPClient.__init__(self, bcastaddr, prog, vers, port) self.reply_handler = None self.timeout = 30 - return self def connsocket(self): # Don't connect -- use sendto @@ -495,8 +494,8 @@ class PortMapperUnpacker(Unpacker): class PartialPortMapperClient: def addpackers(self): - self.packer = PortMapperPacker().init() - self.unpacker = PortMapperUnpacker().init('') + self.packer = PortMapperPacker() + self.unpacker = PortMapperUnpacker('') def Set(self, mapping): return self.make_call(PMAPPROC_SET, mapping, \ @@ -526,23 +525,23 @@ class PartialPortMapperClient: class TCPPortMapperClient(PartialPortMapperClient, RawTCPClient): - def init(self, host): - return RawTCPClient.init(self, \ + def __init__(self, host): + RawTCPClient.__init__(self, \ host, PMAP_PROG, PMAP_VERS, PMAP_PORT) class UDPPortMapperClient(PartialPortMapperClient, RawUDPClient): - def init(self, host): - return RawUDPClient.init(self, \ + def __init__(self, host): + RawUDPClient.__init__(self, \ host, PMAP_PROG, PMAP_VERS, PMAP_PORT) class BroadcastUDPPortMapperClient(PartialPortMapperClient, \ RawBroadcastUDPClient): - def init(self, bcastaddr): - return RawBroadcastUDPClient.init(self, \ + def __init__(self, bcastaddr): + RawBroadcastUDPClient.__init__(self, \ bcastaddr, PMAP_PROG, PMAP_VERS, PMAP_PORT) @@ -550,36 +549,35 @@ class BroadcastUDPPortMapperClient(PartialPortMapperClient, \ class TCPClient(RawTCPClient): - def init(self, host, prog, vers): - pmap = TCPPortMapperClient().init(host) + def __init__(self, host, prog, vers): + pmap = TCPPortMapperClient(host) port = pmap.Getport((prog, vers, IPPROTO_TCP, 0)) pmap.close() if port == 0: raise RuntimeError, 'program not registered' - return RawTCPClient.init(self, host, prog, vers, port) + RawTCPClient.__init__(self, host, prog, vers, port) class UDPClient(RawUDPClient): - def init(self, host, prog, vers): - pmap = UDPPortMapperClient().init(host) + def __init__(self, host, prog, vers): + pmap = UDPPortMapperClient(host) port = pmap.Getport((prog, vers, IPPROTO_UDP, 0)) pmap.close() if port == 0: raise RuntimeError, 'program not registered' - return RawUDPClient.init(self, host, prog, vers, port) + RawUDPClient.__init__(self, host, prog, vers, port) class BroadcastUDPClient(Client): - def init(self, bcastaddr, prog, vers): - self.pmap = BroadcastUDPPortMapperClient().init(bcastaddr) + def __init__(self, bcastaddr, prog, vers): + self.pmap = BroadcastUDPPortMapperClient(bcastaddr) self.pmap.set_reply_handler(self.my_reply_handler) self.prog = prog self.vers = vers self.user_reply_handler = None self.addpackers() - return self def close(self): self.pmap.close() @@ -622,7 +620,7 @@ class BroadcastUDPClient(Client): class Server: - def init(self, host, prog, vers, port): + def __init__(self, host, prog, vers, port): self.host = host # Should normally be '' for default interface self.prog = prog self.vers = vers @@ -631,17 +629,16 @@ class Server: self.bindsocket() self.host, self.port = self.sock.getsockname() self.addpackers() - return self def register(self): mapping = self.prog, self.vers, self.prot, self.port - p = TCPPortMapperClient().init(self.host) + p = TCPPortMapperClient(self.host) if not p.Set(mapping): raise RuntimeError, 'register failed' def unregister(self): mapping = self.prog, self.vers, self.prot, self.port - p = TCPPortMapperClient().init(self.host) + p = TCPPortMapperClient(self.host) if not p.Unset(mapping): raise RuntimeError, 'unregister failed' @@ -716,8 +713,8 @@ class Server: def addpackers(self): # Override this to use derived classes from Packer/Unpacker - self.packer = Packer().init() - self.unpacker = Unpacker().init('') + self.packer = Packer() + self.unpacker = Unpacker('') class TCPServer(Server): @@ -738,10 +735,41 @@ class TCPServer(Server): call = recvrecord(sock) except EOFError: break + except socket.error, msg: + print 'socket error:', msg + break reply = self.handle(call) - if reply <> None: + if reply is not None: sendrecord(sock, reply) + def forkingloop(self): + # Like loop but uses forksession() + self.sock.listen(0) + while 1: + self.forksession(self.sock.accept()) + + def forksession(self, connection): + # Like session but forks off a subprocess + import os + # Wait for deceased children + try: + while 1: + pid, sts = os.waitpid(0, 1) + except os.error: + pass + pid = None + try: + pid = os.fork() + if pid: # Parent + connection[0].close() + return + # Child + self.session(connection) + finally: + # Make sure we don't fall through in the parent + if pid == 0: + os._exit(0) + class UDPServer(Server): @@ -763,8 +791,7 @@ class UDPServer(Server): # Simple test program -- dump local portmapper status def test(): - pmap = UDPPortMapperClient().init('') - pmap.Null() + pmap = UDPPortMapperClient('') list = pmap.Dump() list.sort() for prog, vers, prot, port in list: @@ -786,7 +813,7 @@ def testbcast(): def rh(reply, fromaddr): host, port = fromaddr print host + '\t' + `reply` - pmap = BroadcastUDPPortMapperClient().init(bcastaddr) + pmap = BroadcastUDPPortMapperClient(bcastaddr) pmap.set_reply_handler(rh) pmap.set_timeout(5) replies = pmap.Getport((100002, 1, IPPROTO_UDP, 0)) @@ -806,7 +833,7 @@ def testsvr(): print 'RPC function 1 called, arg', `arg` self.packer.pack_string(arg + arg) # - s = S().init('', 0x20000000, 1, 0) + s = S('', 0x20000000, 1, 0) try: s.unregister() except RuntimeError, msg: @@ -830,7 +857,7 @@ def testclt(): return self.make_call(1, arg, \ self.packer.pack_string, \ self.unpacker.unpack_string) - c = C().init(host, 0x20000000, 1) + c = C(host, 0x20000000, 1) print 'making call...' reply = c.call_1('hello, world, ') print 'call returned', `reply` diff --git a/Demo/rpc/test b/Demo/rpc/test index abb241f..d3c9591 100755 --- a/Demo/rpc/test +++ b/Demo/rpc/test @@ -7,6 +7,7 @@ $PYTHON -c 'from rpc import test; test()' charon.cwi.nl $PYTHON -c 'from rpc import testsvr; testsvr()' & SVR=$! +sleep 2 $PYTHON -c 'from rpc import testclt; testclt()' kill -2 $SVR diff --git a/Demo/rpc/xdr.py b/Demo/rpc/xdr.py index 17a5f92..0c5185e 100644 --- a/Demo/rpc/xdr.py +++ b/Demo/rpc/xdr.py @@ -12,9 +12,8 @@ Long = type(0L) class Packer: - def init(self): + def __init__(self): self.reset() - return self def reset(self): self.buf = '' @@ -47,6 +46,14 @@ class Packer: pack_hyper = pack_uhyper + def pack_float(self, x): + # XXX + self.buf = self.buf + struct.pack('f', x) + + def pack_double(self, x): + # XXX + self.buf = self.buf + struct.pack('d', x) + def pack_fstring(self, n, s): if n < 0: raise ValueError, 'fstring size must be nonnegative' @@ -67,7 +74,7 @@ class Packer: def pack_list(self, list, pack_item): for item in list: self.pack_uint(1) - pack_item(list) + pack_item(item) self.pack_uint(0) def pack_farray(self, n, list, pack_item): @@ -84,9 +91,8 @@ class Packer: class Unpacker: - def init(self, data): + def __init__(self, data): self.reset(data) - return self def reset(self, data): self.buf = data @@ -136,6 +142,24 @@ class Unpacker: if x >= 0x8000000000000000L: x = x - 0x10000000000000000L return x + def unpack_float(self): + # XXX + i = self.pos + self.pos = j = i+4 + data = self.buf[i:j] + if len(data) < 4: + raise EOFError + return struct.unpack('f', data)[0] + + def unpack_double(self): + # XXX + i = self.pos + self.pos = j = i+8 + data = self.buf[i:j] + if len(data) < 8: + raise EOFError + return struct.unpack('8', data)[0] + def unpack_fstring(self, n): if n < 0: raise ValueError, 'fstring size must be nonnegative' @@ -158,11 +182,12 @@ class Unpacker: list = [] while 1: x = self.unpack_uint() - if not x: break + if x == 0: break if x <> 1: raise RuntimeError, \ '0 or 1 expected, got ' + `x` - list.append(unpack_item()) + item = unpack_item() + list.append(item) return list def unpack_farray(self, n, unpack_item): |