symbian-qemu-0.9.1-12/python-2.6.1/Demo/rpc/mountclient.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 # Mount RPC client -- RFC 1094 (NFS), Appendix A
       
     2 
       
     3 # This module demonstrates how to write your own RPC client in Python.
       
     4 # When this example was written, there was no RPC compiler for
       
     5 # Python. Without such a compiler, you must first create classes
       
     6 # derived from Packer and Unpacker to handle the data types for the
       
     7 # server you want to interface to.  You then write the client class.
       
     8 # If you want to support both the TCP and the UDP version of a
       
     9 # protocol, use multiple inheritance as shown below.
       
    10 
       
    11 
       
    12 import rpc
       
    13 from rpc import Packer, Unpacker, TCPClient, UDPClient
       
    14 
       
    15 
       
    16 # Program number and version for the mount protocol
       
    17 MOUNTPROG = 100005
       
    18 MOUNTVERS = 1
       
    19 
       
    20 # Size of the 'fhandle' opaque structure
       
    21 FHSIZE = 32
       
    22 
       
    23 
       
    24 # Packer derived class for Mount protocol clients.
       
    25 # The only thing we need to pack beyond basic types is an 'fhandle'
       
    26 
       
    27 class MountPacker(Packer):
       
    28 
       
    29     def pack_fhandle(self, fhandle):
       
    30         self.pack_fopaque(FHSIZE, fhandle)
       
    31 
       
    32 
       
    33 # Unpacker derived class for Mount protocol clients.
       
    34 # The important types we need to unpack are fhandle, fhstatus,
       
    35 # mountlist and exportlist; mountstruct, exportstruct and groups are
       
    36 # used to unpack components of mountlist and exportlist and the
       
    37 # corresponding functions are passed as function argument to the
       
    38 # generic unpack_list function.
       
    39 
       
    40 class MountUnpacker(Unpacker):
       
    41 
       
    42     def unpack_fhandle(self):
       
    43         return self.unpack_fopaque(FHSIZE)
       
    44 
       
    45     def unpack_fhstatus(self):
       
    46         status = self.unpack_uint()
       
    47         if status == 0:
       
    48             fh = self.unpack_fhandle()
       
    49         else:
       
    50             fh = None
       
    51         return status, fh
       
    52 
       
    53     def unpack_mountlist(self):
       
    54         return self.unpack_list(self.unpack_mountstruct)
       
    55 
       
    56     def unpack_mountstruct(self):
       
    57         hostname = self.unpack_string()
       
    58         directory = self.unpack_string()
       
    59         return (hostname, directory)
       
    60 
       
    61     def unpack_exportlist(self):
       
    62         return self.unpack_list(self.unpack_exportstruct)
       
    63 
       
    64     def unpack_exportstruct(self):
       
    65         filesys = self.unpack_string()
       
    66         groups = self.unpack_groups()
       
    67         return (filesys, groups)
       
    68 
       
    69     def unpack_groups(self):
       
    70         return self.unpack_list(self.unpack_string)
       
    71 
       
    72 
       
    73 # These are the procedures specific to the Mount client class.
       
    74 # Think of this as a derived class of either TCPClient or UDPClient.
       
    75 
       
    76 class PartialMountClient:
       
    77 
       
    78     # This method is called by Client.__init__ to initialize
       
    79     # self.packer and self.unpacker
       
    80     def addpackers(self):
       
    81         self.packer = MountPacker()
       
    82         self.unpacker = MountUnpacker('')
       
    83 
       
    84     # This method is called by Client.__init__ to bind the socket
       
    85     # to a particular network interface and port.  We use the
       
    86     # default network interface, but if we're running as root,
       
    87     # we want to bind to a reserved port
       
    88     def bindsocket(self):
       
    89         import os
       
    90         try:
       
    91             uid = os.getuid()
       
    92         except AttributeError:
       
    93             uid = 1
       
    94         if uid == 0:
       
    95             port = rpc.bindresvport(self.sock, '')
       
    96             # 'port' is not used
       
    97         else:
       
    98             self.sock.bind(('', 0))
       
    99 
       
   100     # This function is called to cough up a suitable
       
   101     # authentication object for a call to procedure 'proc'.
       
   102     def mkcred(self):
       
   103         if self.cred is None:
       
   104             self.cred = rpc.AUTH_UNIX, rpc.make_auth_unix_default()
       
   105         return self.cred
       
   106 
       
   107     # The methods Mnt, Dump etc. each implement one Remote
       
   108     # Procedure Call.  This is done by calling self.make_call()
       
   109     # with as arguments:
       
   110     #
       
   111     # - the procedure number
       
   112     # - the arguments (or None)
       
   113     # - the "packer" function for the arguments (or None)
       
   114     # - the "unpacker" function for the return value (or None)
       
   115     #
       
   116     # The packer and unpacker function, if not None, *must* be
       
   117     # methods of self.packer and self.unpacker, respectively.
       
   118     # A value of None means that there are no arguments or is no
       
   119     # return value, respectively.
       
   120     #
       
   121     # The return value from make_call() is the return value from
       
   122     # the remote procedure call, as unpacked by the "unpacker"
       
   123     # function, or None if the unpacker function is None.
       
   124     #
       
   125     # (Even if you expect a result of None, you should still
       
   126     # return the return value from make_call(), since this may be
       
   127     # needed by a broadcasting version of the class.)
       
   128     #
       
   129     # If the call fails, make_call() raises an exception
       
   130     # (this includes time-outs and invalid results).
       
   131     #
       
   132     # Note that (at least with the UDP protocol) there is no
       
   133     # guarantee that a call is executed at most once.  When you do
       
   134     # get a reply, you know it has been executed at least once;
       
   135     # when you don't get a reply, you know nothing.
       
   136 
       
   137     def Mnt(self, directory):
       
   138         return self.make_call(1, directory, \
       
   139                 self.packer.pack_string, \
       
   140                 self.unpacker.unpack_fhstatus)
       
   141 
       
   142     def Dump(self):
       
   143         return self.make_call(2, None, \
       
   144                 None, self.unpacker.unpack_mountlist)
       
   145 
       
   146     def Umnt(self, directory):
       
   147         return self.make_call(3, directory, \
       
   148                 self.packer.pack_string, None)
       
   149 
       
   150     def Umntall(self):
       
   151         return self.make_call(4, None, None, None)
       
   152 
       
   153     def Export(self):
       
   154         return self.make_call(5, None, \
       
   155                 None, self.unpacker.unpack_exportlist)
       
   156 
       
   157 
       
   158 # We turn the partial Mount client into a full one for either protocol
       
   159 # by use of multiple inheritance.  (In general, when class C has base
       
   160 # classes B1...Bn, if x is an instance of class C, methods of x are
       
   161 # searched first in C, then in B1, then in B2, ..., finally in Bn.)
       
   162 
       
   163 class TCPMountClient(PartialMountClient, TCPClient):
       
   164 
       
   165     def __init__(self, host):
       
   166         TCPClient.__init__(self, host, MOUNTPROG, MOUNTVERS)
       
   167 
       
   168 
       
   169 class UDPMountClient(PartialMountClient, UDPClient):
       
   170 
       
   171     def __init__(self, host):
       
   172         UDPClient.__init__(self, host, MOUNTPROG, MOUNTVERS)
       
   173 
       
   174 
       
   175 # A little test program for the Mount client.  This takes a host as
       
   176 # command line argument (default the local machine), prints its export
       
   177 # list, and attempts to mount and unmount each exported files system.
       
   178 # An optional first argument of -t or -u specifies the protocol to use
       
   179 # (TCP or UDP), default is UDP.
       
   180 
       
   181 def test():
       
   182     import sys
       
   183     if sys.argv[1:] and sys.argv[1] == '-t':
       
   184         C = TCPMountClient
       
   185         del sys.argv[1]
       
   186     elif sys.argv[1:] and sys.argv[1] == '-u':
       
   187         C = UDPMountClient
       
   188         del sys.argv[1]
       
   189     else:
       
   190         C = UDPMountClient
       
   191     if sys.argv[1:]: host = sys.argv[1]
       
   192     else: host = ''
       
   193     mcl = C(host)
       
   194     list = mcl.Export()
       
   195     for item in list:
       
   196         print item
       
   197         try:
       
   198             mcl.Mnt(item[0])
       
   199         except:
       
   200             print 'Sorry'
       
   201             continue
       
   202         mcl.Umnt(item[0])