home *** CD-ROM | disk | FTP | other *** search
- # NFS RPC client -- RFC 1094
-
- # XXX This is not yet complete.
- # XXX Only GETATTR, SETTTR, LOOKUP and READDIR are supported.
-
- # (See mountclient.py for some hints on how to write RPC clients in
- # Python in general)
-
- import rpc
- from rpc import UDPClient, TCPClient
- from mountclient import FHSIZE, MountPacker, MountUnpacker
-
- NFS_PROGRAM = 100003
- NFS_VERSION = 2
-
- # enum stat
- NFS_OK = 0
- # (...many error values...)
-
- # enum ftype
- NFNON = 0
- NFREG = 1
- NFDIR = 2
- NFBLK = 3
- NFCHR = 4
- NFLNK = 5
-
-
- class NFSPacker(MountPacker):
-
- def pack_sattrargs(self, sa):
- file, attributes = sa
- self.pack_fhandle(file)
- self.pack_sattr(attributes)
-
- def pack_sattr(self, sa):
- mode, uid, gid, size, atime, mtime = sa
- self.pack_uint(mode)
- self.pack_uint(uid)
- self.pack_uint(gid)
- self.pack_uint(size)
- self.pack_timeval(atime)
- self.pack_timeval(mtime)
-
- def pack_diropargs(self, da):
- dir, name = da
- self.pack_fhandle(dir)
- self.pack_string(name)
-
- def pack_readdirargs(self, ra):
- dir, cookie, count = ra
- self.pack_fhandle(dir)
- self.pack_uint(cookie)
- self.pack_uint(count)
-
- def pack_timeval(self, tv):
- secs, usecs = tv
- self.pack_uint(secs)
- self.pack_uint(usecs)
-
-
- class NFSUnpacker(MountUnpacker):
-
- def unpack_readdirres(self):
- status = self.unpack_enum()
- if status == NFS_OK:
- entries = self.unpack_list(self.unpack_entry)
- eof = self.unpack_bool()
- rest = (entries, eof)
- else:
- rest = None
- return (status, rest)
-
- def unpack_entry(self):
- fileid = self.unpack_uint()
- name = self.unpack_string()
- cookie = self.unpack_uint()
- return (fileid, name, cookie)
-
- def unpack_diropres(self):
- status = self.unpack_enum()
- if status == NFS_OK:
- fh = self.unpack_fhandle()
- fa = self.unpack_fattr()
- rest = (fh, fa)
- else:
- rest = None
- return (status, rest)
-
- def unpack_attrstat(self):
- status = self.unpack_enum()
- if status == NFS_OK:
- attributes = self.unpack_fattr()
- else:
- attributes = None
- return status, attributes
-
- def unpack_fattr(self):
- type = self.unpack_enum()
- mode = self.unpack_uint()
- nlink = self.unpack_uint()
- uid = self.unpack_uint()
- gid = self.unpack_uint()
- size = self.unpack_uint()
- blocksize = self.unpack_uint()
- rdev = self.unpack_uint()
- blocks = self.unpack_uint()
- fsid = self.unpack_uint()
- fileid = self.unpack_uint()
- atime = self.unpack_timeval()
- mtime = self.unpack_timeval()
- ctime = self.unpack_timeval()
- return (type, mode, nlink, uid, gid, size, blocksize, \
- rdev, blocks, fsid, fileid, atime, mtime, ctime)
-
- def unpack_timeval(self):
- secs = self.unpack_uint()
- usecs = self.unpack_uint()
- return (secs, usecs)
-
-
- class NFSClient(UDPClient):
-
- def __init__(self, host):
- UDPClient.__init__(self, host, NFS_PROGRAM, NFS_VERSION)
-
- def addpackers(self):
- self.packer = NFSPacker()
- self.unpacker = NFSUnpacker('')
-
- def mkcred(self):
- if self.cred == None:
- self.cred = rpc.AUTH_UNIX, rpc.make_auth_unix_default()
- return self.cred
-
- def Getattr(self, fh):
- return self.make_call(1, fh, \
- self.packer.pack_fhandle, \
- self.unpacker.unpack_attrstat)
-
- def Setattr(self, sa):
- return self.make_call(2, sa, \
- self.packer.pack_sattrargs, \
- self.unpacker.unpack_attrstat)
-
- # Root() is obsolete
-
- def Lookup(self, da):
- return self.make_call(4, da, \
- self.packer.pack_diropargs, \
- self.unpacker.unpack_diropres)
-
- # ...
-
- def Readdir(self, ra):
- return self.make_call(16, ra, \
- self.packer.pack_readdirargs, \
- self.unpacker.unpack_readdirres)
-
- # Shorthand to get the entire contents of a directory
- def Listdir(self, dir):
- list = []
- ra = (dir, 0, 2000)
- while 1:
- (status, rest) = self.Readdir(ra)
- if status <> NFS_OK:
- break
- entries, eof = rest
- last_cookie = None
- for fileid, name, cookie in entries:
- list.append(fileid, name)
- last_cookie = cookie
- if eof or last_cookie == None:
- break
- ra = (ra[0], last_cookie, ra[2])
- return list
-
-
- def test():
- import sys
- if sys.argv[1:]: host = sys.argv[1]
- else: host = ''
- if sys.argv[2:]: filesys = sys.argv[2]
- else: filesys = None
- from mountclient import UDPMountClient, TCPMountClient
- mcl = TCPMountClient(host)
- if filesys == None:
- list = mcl.Export()
- for item in list:
- print item
- return
- sf = mcl.Mnt(filesys)
- print sf
- fh = sf[1]
- if fh:
- ncl = NFSClient(host)
- as = ncl.Getattr(fh)
- print as
- list = ncl.Listdir(fh)
- for item in list: print item
- mcl.Umnt(filesys)
-