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