Staging
v0.5.1
https://github.com/python/cpython
Revision 1cd0247a4d1b8282631707ba06b514aeddc75782 authored by Brett Cannon on 09 September 2008, 01:52:27 UTC, committed by Brett Cannon on 09 September 2008, 01:52:27 UTC
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r66321 | brett.cannon | 2008-09-08 17:49:16 -0700 (Mon, 08 Sep 2008) | 7 lines

  warnings.catch_warnings() now returns a list or None instead of the custom
  WarningsRecorder object. This makes the API simpler to use as no special object
  must be learned.

  Closes issue 3781.
  Review by Benjamin Peterson.
........
1 parent 4c19e6e
Raw File
Tip revision: 1cd0247a4d1b8282631707ba06b514aeddc75782 authored by Brett Cannon on 09 September 2008, 01:52:27 UTC
Merged revisions 66321 via svnmerge from
Tip revision: 1cd0247
mountclient.py
# 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 is 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])
back to top