mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			201 lines
		
	
	
	
		
			4.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			201 lines
		
	
	
	
		
			4.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # 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)
 | 
