Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e3cafbe

Browse files
committed
Initial revision
1 parent 5f59d60 commit e3cafbe

5 files changed

Lines changed: 909 additions & 0 deletions

File tree

Demo/rpc/T.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import sys, os, time
2+
3+
def TSTART():
4+
global t0, t1
5+
u, s, cu, cs = os.times()
6+
t0 = u+cu, s+cs, time.millitimer()
7+
8+
def TSTOP(*label):
9+
global t0, t1
10+
u, s, cu, cs = os.times()
11+
t1 = u+cu, s+cs, time.millitimer()
12+
tt = []
13+
for i in range(3):
14+
tt.append(t1[i] - t0[i])
15+
[u, s, r] = tt
16+
msg = ''
17+
for x in label: msg = msg + (x + ' ')
18+
msg = msg + `u` + ' user, ' + `s` + ' sys, ' + `r*0.001` + ' real\n'
19+
sys.stderr.write(msg)

Demo/rpc/mountclient.py

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
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+
11+
from rpc import Packer, Unpacker, TCPClient, UDPClient
12+
13+
MOUNTPROG = 100005
14+
MOUNTVERS = 1
15+
16+
FHSIZE = 32
17+
18+
19+
# Packer derived class for Mount protocol clients.
20+
# The only thing we need to pack beyond basic types is an 'fhandle'
21+
22+
class MountPacker(Packer):
23+
24+
def pack_fhandle(self, fhandle):
25+
self.pack_fopaque(FHSIZE, fhandle)
26+
27+
28+
# Unpacker derived class for Mount protocol clients.
29+
# The important types we need to unpack are fhandle, fhstatus,
30+
# mountlist and exportlist; mountstruct, exportstruct and groups are
31+
# used to unpack components of mountlist and exportlist and the
32+
# corresponding functions are passed as function argument to the
33+
# generic unpack_list function.
34+
35+
class MountUnpacker(Unpacker):
36+
37+
def unpack_fhandle(self):
38+
return self.unpack_fopaque(FHSIZE)
39+
40+
def unpack_fhstatus(self):
41+
status = self.unpack_uint()
42+
if status == 0:
43+
fh = self.unpack_fhandle()
44+
else:
45+
fh = None
46+
return status, fh
47+
48+
def unpack_mountlist(self):
49+
return self.unpack_list(self.unpack_mountstruct)
50+
51+
def unpack_mountstruct(self):
52+
hostname = self.unpack_string()
53+
directory = self.unpack_string()
54+
return (hostname, directory)
55+
56+
def unpack_exportlist(self):
57+
return self.unpack_list(self.unpack_exportstruct)
58+
59+
def unpack_exportstruct(self):
60+
filesys = self.unpack_string()
61+
groups = self.unpack_groups()
62+
return (filesys, groups)
63+
64+
def unpack_groups(self):
65+
return self.unpack_list(self.unpack_string)
66+
67+
68+
# These are the procedures specific to the Mount client class.
69+
# Think of this as a derived class of either TCPClient or UDPClient.
70+
71+
class PartialMountClient:
72+
73+
# This method is called by Client.init to initialize
74+
# self.packer and self.unpacker
75+
def addpackers(self):
76+
self.packer = MountPacker().init()
77+
self.unpacker = MountUnpacker().init('')
78+
79+
# The methods Mnt, Dump etc. each implement one Remote
80+
# Procedure Call. Their general structure is
81+
# self.start_call(<procedure-number>)
82+
# <pack arguments using self.packer>
83+
# self.do_call() # This does the actual message exchange
84+
# <unpack reply using self.unpacker>
85+
# self.end_call()
86+
# return <reply>
87+
# If the call fails, an exception is raised by do_call().
88+
# If the reply does not match what you unpack, an exception is
89+
# raised either during unpacking (if you overrun the buffer)
90+
# or by end_call() (if you leave values in the buffer).
91+
# Calling packer methods with invalid arguments (e.g. if
92+
# invalid arguments were passed from outside) will also result
93+
# in exceptions during packing.
94+
95+
def Mnt(self, directory):
96+
self.start_call(1)
97+
self.packer.pack_string(directory)
98+
self.do_call()
99+
stat = self.unpacker.unpack_fhstatus()
100+
self.end_call()
101+
return stat
102+
103+
def Dump(self):
104+
self.start_call(2)
105+
self.do_call()
106+
list = self.unpacker.unpack_mountlist()
107+
self.end_call()
108+
return list
109+
110+
def Umnt(self, directory):
111+
self.start_call(3)
112+
self.packer.pack_string(directory)
113+
self.do_call()
114+
self.end_call()
115+
116+
def Umntall(self):
117+
self.start_call(4)
118+
self.do_call()
119+
self.end_call()
120+
121+
def Export(self):
122+
self.start_call(5)
123+
self.do_call()
124+
list = self.unpacker.unpack_exportlist()
125+
self.end_call()
126+
return list
127+
128+
129+
# We turn the partial Mount client into a full one for either protocol
130+
# by use of multiple inheritance. (In general, when class C has base
131+
# classes B1...Bn, if x is an instance of class C, methods of x are
132+
# searched first in C, then in B1, then in B2, ..., finally in Bn.)
133+
134+
class TCPMountClient(PartialMountClient, TCPClient):
135+
136+
def init(self, host):
137+
return TCPClient.init(self, host, MOUNTPROG, MOUNTVERS)
138+
139+
140+
class UDPMountClient(PartialMountClient, UDPClient):
141+
142+
def init(self, host):
143+
return UDPClient.init(self, host, MOUNTPROG, MOUNTVERS)
144+
145+
146+
# A little test program for the Mount client. This takes a host as
147+
# command line argument (default the local machine), prints its export
148+
# list, and attempt to mount and unmount each exported files system.
149+
150+
def test():
151+
import sys
152+
if sys.argv[1:]: host = sys.argv[1]
153+
else: host = ''
154+
mcl = UDPMountClient().init(host)
155+
list = mcl.Export()
156+
for item in list:
157+
print item
158+
try:
159+
mcl.Mnt(item[0])
160+
except:
161+
print 'Sorry'
162+
continue
163+
mcl.Umnt(item[0])
164+
return
165+
166+
#test()

Demo/rpc/nfsclient.py

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
# NFS RPC client -- RFC 1094
2+
3+
# (See mountclient.py for some hints on how to write RPC clients in
4+
# Python in general)
5+
6+
from rpc import UDPClient, TCPClient
7+
from mountclient import FHSIZE, MountPacker, MountUnpacker
8+
9+
NFS_PROGRAM = 100003
10+
NFS_VERSION = 2
11+
12+
# enum stat
13+
NFS_OK = 0
14+
# (...many error values...)
15+
16+
# enum ftype
17+
NFNON = 0
18+
NFREG = 1
19+
NFDIR = 2
20+
NFBLK = 3
21+
NFCHR = 4
22+
NFLNK = 5
23+
24+
25+
class NFSPacker(MountPacker):
26+
27+
def pack_sattrargs(self, sa):
28+
file, attributes = sa
29+
self.pack_fhandle(file)
30+
self.pack_sattr(attributes)
31+
32+
def pack_sattr(self, sa):
33+
mode, uid, gid, size, atime, mtime = sa
34+
self.pack_uint(mode)
35+
self.pack_uint(uid)
36+
self.pack_uint(gid)
37+
self.pack_uint(size)
38+
self.pack_timeval(atime)
39+
self.pack_timeval(mtime)
40+
41+
def pack_diropargs(self, da):
42+
dir, name = da
43+
self.pack_fhandle(dir)
44+
self.pack_string(name)
45+
46+
def pack_readdirargs(self, ra):
47+
dir, cookie, count = ra
48+
self.pack_fhandle(dir)
49+
self.pack_uint(cookie)
50+
self.pack_uint(count)
51+
52+
def pack_timeval(self, tv):
53+
secs, usecs = tv
54+
self.pack_uint(secs)
55+
self.pack_uint(usecs)
56+
57+
58+
class NFSUnpacker(MountUnpacker):
59+
60+
def unpack_readdirres(self):
61+
status = self.unpack_enum()
62+
if status == NFS_OK:
63+
entries = self.unpack_list(self.unpack_entry)
64+
eof = self.unpack_bool()
65+
rest = (entries, eof)
66+
else:
67+
rest = None
68+
return (status, rest)
69+
70+
def unpack_entry(self):
71+
fileid = self.unpack_uint()
72+
name = self.unpack_string()
73+
cookie = self.unpack_uint()
74+
return (fileid, name, cookie)
75+
76+
def unpack_diropres(self):
77+
status = self.unpack_enum()
78+
if status == NFS_OK:
79+
fh = self.unpack_fhandle()
80+
fa = self.unpack_fattr()
81+
rest = (fh, fa)
82+
else:
83+
rest = None
84+
return (status, rest)
85+
86+
def unpack_attrstat(self):
87+
status = self.unpack_enum()
88+
if status == NFS_OK:
89+
attributes = self.unpack_fattr()
90+
else:
91+
attributes = None
92+
return status, attributes
93+
94+
def unpack_fattr(self):
95+
type = self.unpack_enum()
96+
mode = self.unpack_uint()
97+
nlink = self.unpack_uint()
98+
uid = self.unpack_uint()
99+
gid = self.unpack_uint()
100+
size = self.unpack_uint()
101+
blocksize = self.unpack_uint()
102+
rdev = self.unpack_uint()
103+
blocks = self.unpack_uint()
104+
fsid = self.unpack_uint()
105+
fileid = self.unpack_uint()
106+
atime = self.unpack_timeval()
107+
mtime = self.unpack_timeval()
108+
ctime = self.unpack_timeval()
109+
return (type, mode, nlink, uid, gid, size, blocksize, \
110+
rdev, blocks, fsid, fileid, atime, mtime, ctime)
111+
112+
def unpack_timeval(self):
113+
secs = self.unpack_uint()
114+
usecs = self.unpack_uint()
115+
return (secs, usecs)
116+
117+
118+
class NFSClient(UDPClient):
119+
120+
def init(self, host):
121+
return UDPClient.init(self, host, NFS_PROGRAM, NFS_VERSION)
122+
123+
def addpackers(self):
124+
self.packer = NFSPacker().init()
125+
self.unpacker = NFSUnpacker().init('')
126+
127+
def Getattr(self, fh):
128+
self.start_call(1)
129+
self.packer.pack_fhandle(fh)
130+
self.do_call()
131+
as = self.unpacker.unpack_attrstat()
132+
self.end_call()
133+
return as
134+
135+
def Setattr(self, sa):
136+
self.start_call(2)
137+
self.packer.pack_sattrargs(sa)
138+
self.do_call()
139+
as = self.unpacker.unpack_attrstat()
140+
self.end_call()
141+
return as
142+
143+
# Root() is obsolete
144+
145+
def Lookup(self, da):
146+
self.start_call(4)
147+
self.packer.pack_diropargs(da)
148+
self.do_call()
149+
dr = self.unpacker.unpack_diropres()
150+
self.end_call()
151+
return dr
152+
153+
# ...
154+
155+
def Readdir(self, ra):
156+
self.start_call(16)
157+
self.packer.pack_readdirargs(ra)
158+
self.do_call()
159+
rr = self.unpacker.unpack_readdirres()
160+
self.end_call()
161+
return rr
162+
163+
# Shorthand to get the entire contents of a directory
164+
def Listdir(self, dir):
165+
list = []
166+
ra = (dir, 0, 16)
167+
while 1:
168+
(status, rest) = self.Readdir(ra)
169+
if status <> NFS_OK:
170+
break
171+
entries, eof = rest
172+
last_cookie = None
173+
for fileid, name, cookie in entries:
174+
print (fileid, name, cookie) # XXX
175+
list.append(fileid, name)
176+
last_cookie = cookie
177+
if eof or not last_cookie:
178+
break
179+
ra = (ra[0], last_cookie, ra[2])
180+
return list
181+
182+
183+
def test():
184+
import sys
185+
if sys.argv[1:]: host = sys.argv[1]
186+
else: host = ''
187+
if sys.argv[2:]: filesys = sys.argv[2]
188+
else: filesys = None
189+
from mountclient import UDPMountClient, TCPMountClient
190+
mcl = TCPMountClient().init(host)
191+
if filesys == None:
192+
list = mcl.Export()
193+
for item in list:
194+
print item
195+
return
196+
sf = mcl.Mnt(filesys)
197+
print sf
198+
fh = sf[1]
199+
if fh:
200+
ncl = NFSClient().init(host)
201+
as = ncl.Getattr(fh)
202+
print as
203+
list = ncl.Listdir(fh)
204+
for item in list: print item
205+
mcl.Unmnt(filesys)
206+
207+
test()

0 commit comments

Comments
 (0)