Commit 9e80d6f1 authored by Guido van Rossum's avatar Guido van Rossum

*** empty log message ***

parent 7565b934
...@@ -6,4 +6,5 @@ ...@@ -6,4 +6,5 @@
mountclient.py 1 mountclient.py 1
nfsclient.py 1 nfsclient.py 1
rpc.py 1 rpc.py 1
test 1
xdr.py 1 xdr.py 1
...@@ -21,13 +21,3 @@ Other clients are tested similarly. ...@@ -21,13 +21,3 @@ Other clients are tested similarly.
For hostname, use e.g. wuarchive.wustl.edu or gatekeeper.dec.com (two For hostname, use e.g. wuarchive.wustl.edu or gatekeeper.dec.com (two
hosts that are known to export NFS filesystems with little restrictions). 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"
...@@ -74,13 +74,13 @@ class MountUnpacker(Unpacker): ...@@ -74,13 +74,13 @@ class MountUnpacker(Unpacker):
class PartialMountClient: 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 # self.packer and self.unpacker
def addpackers(self): def addpackers(self):
self.packer = MountPacker().init() self.packer = MountPacker()
self.unpacker = MountUnpacker().init('') 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 # to a particular network interface and port. We use the
# default network interface, but if we're running as root, # default network interface, but if we're running as root,
# we want to bind to a reserved port # we want to bind to a reserved port
...@@ -161,14 +161,14 @@ class PartialMountClient: ...@@ -161,14 +161,14 @@ class PartialMountClient:
class TCPMountClient(PartialMountClient, TCPClient): class TCPMountClient(PartialMountClient, TCPClient):
def init(self, host): def __init__(self, host):
return TCPClient.init(self, host, MOUNTPROG, MOUNTVERS) TCPClient.__init__(self, host, MOUNTPROG, MOUNTVERS)
class UDPMountClient(PartialMountClient, UDPClient): class UDPMountClient(PartialMountClient, UDPClient):
def init(self, host): def __init__(self, host):
return UDPClient.init(self, host, MOUNTPROG, MOUNTVERS) UDPClient.__init__(self, host, MOUNTPROG, MOUNTVERS)
# A little test program for the Mount client. This takes a host as # A little test program for the Mount client. This takes a host as
...@@ -189,7 +189,7 @@ def test(): ...@@ -189,7 +189,7 @@ def test():
C = UDPMountClient C = UDPMountClient
if sys.argv[1:]: host = sys.argv[1] if sys.argv[1:]: host = sys.argv[1]
else: host = '' else: host = ''
mcl = C().init(host) mcl = C(host)
list = mcl.Export() list = mcl.Export()
for item in list: for item in list:
print item print item
......
...@@ -121,12 +121,12 @@ class NFSUnpacker(MountUnpacker): ...@@ -121,12 +121,12 @@ class NFSUnpacker(MountUnpacker):
class NFSClient(UDPClient): class NFSClient(UDPClient):
def init(self, host): def __init__(self, host):
return UDPClient.init(self, host, NFS_PROGRAM, NFS_VERSION) UDPClient.__init__(self, host, NFS_PROGRAM, NFS_VERSION)
def addpackers(self): def addpackers(self):
self.packer = NFSPacker().init() self.packer = NFSPacker()
self.unpacker = NFSUnpacker().init('') self.unpacker = NFSUnpacker('')
def mkcred(self): def mkcred(self):
if self.cred == None: if self.cred == None:
...@@ -183,7 +183,7 @@ def test(): ...@@ -183,7 +183,7 @@ def test():
if sys.argv[2:]: filesys = sys.argv[2] if sys.argv[2:]: filesys = sys.argv[2]
else: filesys = None else: filesys = None
from mountclient import UDPMountClient, TCPMountClient from mountclient import UDPMountClient, TCPMountClient
mcl = TCPMountClient().init(host) mcl = TCPMountClient(host)
if filesys == None: if filesys == None:
list = mcl.Export() list = mcl.Export()
for item in list: for item in list:
...@@ -193,7 +193,7 @@ def test(): ...@@ -193,7 +193,7 @@ def test():
print sf print sf
fh = sf[1] fh = sf[1]
if fh: if fh:
ncl = NFSClient().init(host) ncl = NFSClient(host)
as = ncl.Getattr(fh) as = ncl.Getattr(fh)
print as print as
list = ncl.Listdir(fh) list = ncl.Listdir(fh)
......
...@@ -37,8 +37,8 @@ class RnusersUnpacker(Unpacker): ...@@ -37,8 +37,8 @@ class RnusersUnpacker(Unpacker):
class PartialRnusersClient: class PartialRnusersClient:
def addpackers(self): def addpackers(self):
self.packer = RnusersPacker().init() self.packer = RnusersPacker()
self.unpacker = RnusersUnpacker().init('') self.unpacker = RnusersUnpacker('')
def Num(self): def Num(self):
return self.make_call(1, None, None, self.unpacker.unpack_int) return self.make_call(1, None, None, self.unpacker.unpack_int)
...@@ -54,14 +54,14 @@ class PartialRnusersClient: ...@@ -54,14 +54,14 @@ class PartialRnusersClient:
class RnusersClient(PartialRnusersClient, UDPClient): class RnusersClient(PartialRnusersClient, UDPClient):
def init(self, host): def __init__(self, host):
return UDPClient.init(self, host, 100002, 2) UDPClient.__init__(self, host, 100002, 2)
class BroadcastRnusersClient(PartialRnusersClient, BroadcastUDPClient): class BroadcastRnusersClient(PartialRnusersClient, BroadcastUDPClient):
def init(self, bcastaddr): def __init__(self, bcastaddr):
return BroadcastUDPClient.init(self, bcastaddr, 100002, 2) BroadcastUDPClient.__init__(self, bcastaddr, 100002, 2)
def test(): def test():
...@@ -71,7 +71,7 @@ def test(): ...@@ -71,7 +71,7 @@ def test():
return return
else: else:
host = sys.argv[1] host = sys.argv[1]
c = RnusersClient().init(host) c = RnusersClient(host)
list = c.Names() list = c.Names()
for (line, name, host, time), idle in list: for (line, name, host, time), idle in list:
line = strip0(line) line = strip0(line)
...@@ -80,7 +80,7 @@ def test(): ...@@ -80,7 +80,7 @@ def test():
print `name`, `host`, `line`, time, idle print `name`, `host`, `line`, time, idle
def testbcast(): def testbcast():
c = BroadcastRnusersClient().init('<broadcast>') c = BroadcastRnusersClient('<broadcast>')
def listit(list, fromaddr): def listit(list, fromaddr):
host, port = fromaddr host, port = fromaddr
print host + '\t:', print host + '\t:',
......
...@@ -151,7 +151,7 @@ def make_auth_null(): ...@@ -151,7 +151,7 @@ def make_auth_null():
return '' return ''
def make_auth_unix(seed, host, uid, gid, groups): def make_auth_unix(seed, host, uid, gid, groups):
p = Packer().init() p = Packer()
p.pack_auth_unix(seed, host, uid, gid, groups) p.pack_auth_unix(seed, host, uid, gid, groups)
return p.get_buf() return p.get_buf()
...@@ -163,14 +163,15 @@ def make_auth_unix_default(): ...@@ -163,14 +163,15 @@ def make_auth_unix_default():
except ImportError: except ImportError:
uid = gid = 0 uid = gid = 0
import time 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 # Common base class for clients
class Client: class Client:
def init(self, host, prog, vers, port): def __init__(self, host, prog, vers, port):
self.host = host self.host = host
self.prog = prog self.prog = prog
self.vers = vers self.vers = vers
...@@ -182,7 +183,6 @@ class Client: ...@@ -182,7 +183,6 @@ class Client:
self.addpackers() self.addpackers()
self.cred = None self.cred = None
self.verf = None self.verf = None
return self
def close(self): def close(self):
self.sock.close() self.sock.close()
...@@ -201,8 +201,8 @@ class Client: ...@@ -201,8 +201,8 @@ class Client:
def addpackers(self): def addpackers(self):
# Override this to use derived classes from Packer/Unpacker # Override this to use derived classes from Packer/Unpacker
self.packer = Packer().init() self.packer = Packer()
self.unpacker = Unpacker().init('') self.unpacker = Unpacker('')
def make_call(self, proc, args, pack_func, unpack_func): def make_call(self, proc, args, pack_func, unpack_func):
# Don't normally override this (but see Broadcast) # Don't normally override this (but see Broadcast)
...@@ -244,7 +244,7 @@ class Client: ...@@ -244,7 +244,7 @@ class Client:
self.verf = (AUTH_NULL, make_auth_null()) self.verf = (AUTH_NULL, make_auth_null())
return self.verf 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) return self.make_call(0, None, None, None)
...@@ -369,11 +369,10 @@ class RawUDPClient(Client): ...@@ -369,11 +369,10 @@ class RawUDPClient(Client):
class RawBroadcastUDPClient(RawUDPClient): class RawBroadcastUDPClient(RawUDPClient):
def init(self, bcastaddr, prog, vers, port): def __init__(self, bcastaddr, prog, vers, port):
self = RawUDPClient.init(self, bcastaddr, prog, vers, port) RawUDPClient.__init__(self, bcastaddr, prog, vers, port)
self.reply_handler = None self.reply_handler = None
self.timeout = 30 self.timeout = 30
return self
def connsocket(self): def connsocket(self):
# Don't connect -- use sendto # Don't connect -- use sendto
...@@ -495,8 +494,8 @@ class PortMapperUnpacker(Unpacker): ...@@ -495,8 +494,8 @@ class PortMapperUnpacker(Unpacker):
class PartialPortMapperClient: class PartialPortMapperClient:
def addpackers(self): def addpackers(self):
self.packer = PortMapperPacker().init() self.packer = PortMapperPacker()
self.unpacker = PortMapperUnpacker().init('') self.unpacker = PortMapperUnpacker('')
def Set(self, mapping): def Set(self, mapping):
return self.make_call(PMAPPROC_SET, mapping, \ return self.make_call(PMAPPROC_SET, mapping, \
...@@ -526,23 +525,23 @@ class PartialPortMapperClient: ...@@ -526,23 +525,23 @@ class PartialPortMapperClient:
class TCPPortMapperClient(PartialPortMapperClient, RawTCPClient): class TCPPortMapperClient(PartialPortMapperClient, RawTCPClient):
def init(self, host): def __init__(self, host):
return RawTCPClient.init(self, \ RawTCPClient.__init__(self, \
host, PMAP_PROG, PMAP_VERS, PMAP_PORT) host, PMAP_PROG, PMAP_VERS, PMAP_PORT)
class UDPPortMapperClient(PartialPortMapperClient, RawUDPClient): class UDPPortMapperClient(PartialPortMapperClient, RawUDPClient):
def init(self, host): def __init__(self, host):
return RawUDPClient.init(self, \ RawUDPClient.__init__(self, \
host, PMAP_PROG, PMAP_VERS, PMAP_PORT) host, PMAP_PROG, PMAP_VERS, PMAP_PORT)
class BroadcastUDPPortMapperClient(PartialPortMapperClient, \ class BroadcastUDPPortMapperClient(PartialPortMapperClient, \
RawBroadcastUDPClient): RawBroadcastUDPClient):
def init(self, bcastaddr): def __init__(self, bcastaddr):
return RawBroadcastUDPClient.init(self, \ RawBroadcastUDPClient.__init__(self, \
bcastaddr, PMAP_PROG, PMAP_VERS, PMAP_PORT) bcastaddr, PMAP_PROG, PMAP_VERS, PMAP_PORT)
...@@ -550,36 +549,35 @@ class BroadcastUDPPortMapperClient(PartialPortMapperClient, \ ...@@ -550,36 +549,35 @@ class BroadcastUDPPortMapperClient(PartialPortMapperClient, \
class TCPClient(RawTCPClient): class TCPClient(RawTCPClient):
def init(self, host, prog, vers): def __init__(self, host, prog, vers):
pmap = TCPPortMapperClient().init(host) pmap = TCPPortMapperClient(host)
port = pmap.Getport((prog, vers, IPPROTO_TCP, 0)) port = pmap.Getport((prog, vers, IPPROTO_TCP, 0))
pmap.close() pmap.close()
if port == 0: if port == 0:
raise RuntimeError, 'program not registered' raise RuntimeError, 'program not registered'
return RawTCPClient.init(self, host, prog, vers, port) RawTCPClient.__init__(self, host, prog, vers, port)
class UDPClient(RawUDPClient): class UDPClient(RawUDPClient):
def init(self, host, prog, vers): def __init__(self, host, prog, vers):
pmap = UDPPortMapperClient().init(host) pmap = UDPPortMapperClient(host)
port = pmap.Getport((prog, vers, IPPROTO_UDP, 0)) port = pmap.Getport((prog, vers, IPPROTO_UDP, 0))
pmap.close() pmap.close()
if port == 0: if port == 0:
raise RuntimeError, 'program not registered' raise RuntimeError, 'program not registered'
return RawUDPClient.init(self, host, prog, vers, port) RawUDPClient.__init__(self, host, prog, vers, port)
class BroadcastUDPClient(Client): class BroadcastUDPClient(Client):
def init(self, bcastaddr, prog, vers): def __init__(self, bcastaddr, prog, vers):
self.pmap = BroadcastUDPPortMapperClient().init(bcastaddr) self.pmap = BroadcastUDPPortMapperClient(bcastaddr)
self.pmap.set_reply_handler(self.my_reply_handler) self.pmap.set_reply_handler(self.my_reply_handler)
self.prog = prog self.prog = prog
self.vers = vers self.vers = vers
self.user_reply_handler = None self.user_reply_handler = None
self.addpackers() self.addpackers()
return self
def close(self): def close(self):
self.pmap.close() self.pmap.close()
...@@ -622,7 +620,7 @@ class BroadcastUDPClient(Client): ...@@ -622,7 +620,7 @@ class BroadcastUDPClient(Client):
class Server: 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.host = host # Should normally be '' for default interface
self.prog = prog self.prog = prog
self.vers = vers self.vers = vers
...@@ -631,17 +629,16 @@ class Server: ...@@ -631,17 +629,16 @@ class Server:
self.bindsocket() self.bindsocket()
self.host, self.port = self.sock.getsockname() self.host, self.port = self.sock.getsockname()
self.addpackers() self.addpackers()
return self
def register(self): def register(self):
mapping = self.prog, self.vers, self.prot, self.port mapping = self.prog, self.vers, self.prot, self.port
p = TCPPortMapperClient().init(self.host) p = TCPPortMapperClient(self.host)
if not p.Set(mapping): if not p.Set(mapping):
raise RuntimeError, 'register failed' raise RuntimeError, 'register failed'
def unregister(self): def unregister(self):
mapping = self.prog, self.vers, self.prot, self.port mapping = self.prog, self.vers, self.prot, self.port
p = TCPPortMapperClient().init(self.host) p = TCPPortMapperClient(self.host)
if not p.Unset(mapping): if not p.Unset(mapping):
raise RuntimeError, 'unregister failed' raise RuntimeError, 'unregister failed'
...@@ -716,8 +713,8 @@ class Server: ...@@ -716,8 +713,8 @@ class Server:
def addpackers(self): def addpackers(self):
# Override this to use derived classes from Packer/Unpacker # Override this to use derived classes from Packer/Unpacker
self.packer = Packer().init() self.packer = Packer()
self.unpacker = Unpacker().init('') self.unpacker = Unpacker('')
class TCPServer(Server): class TCPServer(Server):
...@@ -738,10 +735,41 @@ class TCPServer(Server): ...@@ -738,10 +735,41 @@ class TCPServer(Server):
call = recvrecord(sock) call = recvrecord(sock)
except EOFError: except EOFError:
break break
except socket.error, msg:
print 'socket error:', msg
break
reply = self.handle(call) reply = self.handle(call)
if reply <> None: if reply is not None:
sendrecord(sock, reply) 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): class UDPServer(Server):
...@@ -763,8 +791,7 @@ class UDPServer(Server): ...@@ -763,8 +791,7 @@ class UDPServer(Server):
# Simple test program -- dump local portmapper status # Simple test program -- dump local portmapper status
def test(): def test():
pmap = UDPPortMapperClient().init('') pmap = UDPPortMapperClient('')
pmap.Null()
list = pmap.Dump() list = pmap.Dump()
list.sort() list.sort()
for prog, vers, prot, port in list: for prog, vers, prot, port in list:
...@@ -786,7 +813,7 @@ def testbcast(): ...@@ -786,7 +813,7 @@ def testbcast():
def rh(reply, fromaddr): def rh(reply, fromaddr):
host, port = fromaddr host, port = fromaddr
print host + '\t' + `reply` print host + '\t' + `reply`
pmap = BroadcastUDPPortMapperClient().init(bcastaddr) pmap = BroadcastUDPPortMapperClient(bcastaddr)
pmap.set_reply_handler(rh) pmap.set_reply_handler(rh)
pmap.set_timeout(5) pmap.set_timeout(5)
replies = pmap.Getport((100002, 1, IPPROTO_UDP, 0)) replies = pmap.Getport((100002, 1, IPPROTO_UDP, 0))
...@@ -806,7 +833,7 @@ def testsvr(): ...@@ -806,7 +833,7 @@ def testsvr():
print 'RPC function 1 called, arg', `arg` print 'RPC function 1 called, arg', `arg`
self.packer.pack_string(arg + arg) self.packer.pack_string(arg + arg)
# #
s = S().init('', 0x20000000, 1, 0) s = S('', 0x20000000, 1, 0)
try: try:
s.unregister() s.unregister()
except RuntimeError, msg: except RuntimeError, msg:
...@@ -830,7 +857,7 @@ def testclt(): ...@@ -830,7 +857,7 @@ def testclt():
return self.make_call(1, arg, \ return self.make_call(1, arg, \
self.packer.pack_string, \ self.packer.pack_string, \
self.unpacker.unpack_string) self.unpacker.unpack_string)
c = C().init(host, 0x20000000, 1) c = C(host, 0x20000000, 1)
print 'making call...' print 'making call...'
reply = c.call_1('hello, world, ') reply = c.call_1('hello, world, ')
print 'call returned', `reply` print 'call returned', `reply`
...@@ -7,6 +7,7 @@ $PYTHON -c 'from rpc import test; test()' charon.cwi.nl ...@@ -7,6 +7,7 @@ $PYTHON -c 'from rpc import test; test()' charon.cwi.nl
$PYTHON -c 'from rpc import testsvr; testsvr()' & $PYTHON -c 'from rpc import testsvr; testsvr()' &
SVR=$! SVR=$!
sleep 2
$PYTHON -c 'from rpc import testclt; testclt()' $PYTHON -c 'from rpc import testclt; testclt()'
kill -2 $SVR kill -2 $SVR
......
...@@ -12,9 +12,8 @@ Long = type(0L) ...@@ -12,9 +12,8 @@ Long = type(0L)
class Packer: class Packer:
def init(self): def __init__(self):
self.reset() self.reset()
return self
def reset(self): def reset(self):
self.buf = '' self.buf = ''
...@@ -47,6 +46,14 @@ class Packer: ...@@ -47,6 +46,14 @@ class Packer:
pack_hyper = pack_uhyper 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): def pack_fstring(self, n, s):
if n < 0: if n < 0:
raise ValueError, 'fstring size must be nonnegative' raise ValueError, 'fstring size must be nonnegative'
...@@ -67,7 +74,7 @@ class Packer: ...@@ -67,7 +74,7 @@ class Packer:
def pack_list(self, list, pack_item): def pack_list(self, list, pack_item):
for item in list: for item in list:
self.pack_uint(1) self.pack_uint(1)
pack_item(list) pack_item(item)
self.pack_uint(0) self.pack_uint(0)
def pack_farray(self, n, list, pack_item): def pack_farray(self, n, list, pack_item):
...@@ -84,9 +91,8 @@ class Packer: ...@@ -84,9 +91,8 @@ class Packer:
class Unpacker: class Unpacker:
def init(self, data): def __init__(self, data):
self.reset(data) self.reset(data)
return self
def reset(self, data): def reset(self, data):
self.buf = data self.buf = data
...@@ -136,6 +142,24 @@ class Unpacker: ...@@ -136,6 +142,24 @@ class Unpacker:
if x >= 0x8000000000000000L: x = x - 0x10000000000000000L if x >= 0x8000000000000000L: x = x - 0x10000000000000000L
return x 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): def unpack_fstring(self, n):
if n < 0: if n < 0:
raise ValueError, 'fstring size must be nonnegative' raise ValueError, 'fstring size must be nonnegative'
...@@ -158,11 +182,12 @@ class Unpacker: ...@@ -158,11 +182,12 @@ class Unpacker:
list = [] list = []
while 1: while 1:
x = self.unpack_uint() x = self.unpack_uint()
if not x: break if x == 0: break
if x <> 1: if x <> 1:
raise RuntimeError, \ raise RuntimeError, \
'0 or 1 expected, got ' + `x` '0 or 1 expected, got ' + `x`
list.append(unpack_item()) item = unpack_item()
list.append(item)
return list return list
def unpack_farray(self, n, unpack_item): def unpack_farray(self, n, unpack_item):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment