# Mount RPC client -- RFC 1094 (NFS), Appendix A

# This module demonstrates how to write your own RPC client in Python.
# When this example was written, there was no RPC compiler for
# Python. Without such a compiler, you must first create classes
# derived from Packer and Unpacker to handle the data types for the
# server you want to interface to.  You then write the client class.
# If you want to support both the TCP and the UDP version of a
# protocol, use multiple inheritance as shown below.


import rpc
from rpc import Packer, Unpacker, TCPClient, UDPClient


# Program number and version for the mount protocol
MOUNTPROG = 100005
MOUNTVERS = 1

# Size of the 'fhandle' opaque structure
FHSIZE = 32


# Packer derived class for Mount protocol clients.
# The only thing we need to pack beyond basic types is an 'fhandle'

class MountPacker(Packer):

	def pack_fhandle(self, fhandle):
		self.pack_fopaque(FHSIZE, fhandle)


# Unpacker derived class for Mount protocol clients.
# The important types we need to unpack are fhandle, fhstatus,
# mountlist and exportlist; mountstruct, exportstruct and groups are
# used to unpack components of mountlist and exportlist and the
# corresponding functions are passed as function argument to the
# generic unpack_list function.

class MountUnpacker(Unpacker):

	def unpack_fhandle(self):
		return self.unpack_fopaque(FHSIZE)

	def unpack_fhstatus(self):
		status = self.unpack_uint()
		if status == 0:
			fh = self.unpack_fhandle()
		else:
			fh = None
		return status, fh

	def unpack_mountlist(self):
		return self.unpack_list(self.unpack_mountstruct)

	def unpack_mountstruct(self):
		hostname = self.unpack_string()
		directory = self.unpack_string()
		return (hostname, directory)

	def unpack_exportlist(self):
		return self.unpack_list(self.unpack_exportstruct)

	def unpack_exportstruct(self):
		filesys = self.unpack_string()
		groups = self.unpack_groups()
		return (filesys, groups)

	def unpack_groups(self):
		return self.unpack_list(self.unpack_string)


# These are the procedures specific to the Mount client class.
# Think of this as a derived class of either TCPClient or UDPClient.

class PartialMountClient:

	# This method is called by Client.__init__ to initialize
	# self.packer and self.unpacker
	def addpackers(self):
		self.packer = MountPacker()
		self.unpacker = MountUnpacker('')

	# 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
	def bindsocket(self):
		import os
		try:
			uid = os.getuid()
		except AttributeError:
			uid = 1
		if uid == 0:
			port = rpc.bindresvport(self.sock, '')
			# 'port' is not used
		else:
			self.sock.bind(('', 0))

	# This function is called to cough up a suitable
	# authentication object for a call to procedure 'proc'.
	def mkcred(self):
		if self.cred == None:
			self.cred = rpc.AUTH_UNIX, rpc.make_auth_unix_default()
		return self.cred

	# The methods Mnt, Dump etc. each implement one Remote
	# Procedure Call.  This is done by calling self.make_call()
	# with as arguments:
	#
	# - the procedure number
	# - the arguments (or None)
	# - the "packer" function for the arguments (or None)
	# - the "unpacker" function for the return value (or None)
	#
	# The packer and unpacker function, if not None, *must* be
	# methods of self.packer and self.unpacker, respectively.
	# A value of None means that there are no arguments or is no
	# return value, respectively.
	#
	# The return value from make_call() is the return value from
	# the remote procedure call, as unpacked by the "unpacker"
	# function, or None if the unpacker function is None.
	#
	# (Even if you expect a result of None, you should still
	# return the return value from make_call(), since this may be
	# needed by a broadcasting version of the class.)
	#
	# If the call fails, make_call() raises an exception
	# (this includes time-outs and invalid results).
	#
	# Note that (at least with the UDP protocol) there is no
	# guarantee that a call is executed at most once.  When you do
	# get a reply, you know it has been executed at least once;
	# when you don't get a reply, you know nothing.

	def Mnt(self, directory):
		return self.make_call(1, directory, \
			self.packer.pack_string, \
			self.unpacker.unpack_fhstatus)

	def Dump(self):
		return self.make_call(2, None, \
			None, self.unpacker.unpack_mountlist)

	def Umnt(self, directory):
		return self.make_call(3, directory, \
			self.packer.pack_string, None)

	def Umntall(self):
		return self.make_call(4, None, None, None)

	def Export(self):
		return self.make_call(5, None, \
			None, self.unpacker.unpack_exportlist)


# We turn the partial Mount client into a full one for either protocol
# by use of multiple inheritance.  (In general, when class C has base
# classes B1...Bn, if x is an instance of class C, methods of x are
# searched first in C, then in B1, then in B2, ..., finally in Bn.)

class TCPMountClient(PartialMountClient, TCPClient):

	def __init__(self, host):
		TCPClient.__init__(self, host, MOUNTPROG, MOUNTVERS)


class UDPMountClient(PartialMountClient, UDPClient):

	def __init__(self, host):
		UDPClient.__init__(self, host, MOUNTPROG, MOUNTVERS)


# A little test program for the Mount client.  This takes a host as
# command line argument (default the local machine), prints its export
# list, and attempts to mount and unmount each exported files system.
# An optional first argument of -t or -u specifies the protocol to use
# (TCP or UDP), default is UDP.

def test():
	import sys
	if sys.argv[1:] and sys.argv[1] == '-t':
		C = TCPMountClient
		del sys.argv[1]
	elif sys.argv[1:] and sys.argv[1] == '-u':
		C = UDPMountClient
		del sys.argv[1]
	else:
		C = UDPMountClient
	if sys.argv[1:]: host = sys.argv[1]
	else: host = ''
	mcl = C(host)
	list = mcl.Export()
	for item in list:
		print item
		try:
			mcl.Mnt(item[0])
		except:
			print 'Sorry'
			continue
		mcl.Umnt(item[0])
