mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 11:49:12 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			201 lines
		
	
	
	
		
			4.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			201 lines
		
	
	
	
		
			4.3 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)
 |