blob: 37ec46c047f9ebfcc4cd9778f8a38dce4e90716b [file] [log] [blame]
Guido van Rossume3cafbe1992-12-14 23:25:04 +00001# NFS RPC client -- RFC 1094
2
Guido van Rossumfa83c7b1992-12-17 17:12:38 +00003# XXX This is not yet complete.
4# XXX Only GETATTR, SETTTR, LOOKUP and READDIR are supported.
5
Guido van Rossume3cafbe1992-12-14 23:25:04 +00006# (See mountclient.py for some hints on how to write RPC clients in
7# Python in general)
8
Guido van Rossum195a4f71992-12-15 20:52:31 +00009import rpc
Guido van Rossume3cafbe1992-12-14 23:25:04 +000010from rpc import UDPClient, TCPClient
11from mountclient import FHSIZE, MountPacker, MountUnpacker
12
13NFS_PROGRAM = 100003
14NFS_VERSION = 2
15
16# enum stat
17NFS_OK = 0
18# (...many error values...)
19
20# enum ftype
21NFNON = 0
22NFREG = 1
23NFDIR = 2
24NFBLK = 3
25NFCHR = 4
26NFLNK = 5
27
28
29class NFSPacker(MountPacker):
30
31 def pack_sattrargs(self, sa):
32 file, attributes = sa
33 self.pack_fhandle(file)
34 self.pack_sattr(attributes)
35
36 def pack_sattr(self, sa):
37 mode, uid, gid, size, atime, mtime = sa
38 self.pack_uint(mode)
39 self.pack_uint(uid)
40 self.pack_uint(gid)
41 self.pack_uint(size)
42 self.pack_timeval(atime)
43 self.pack_timeval(mtime)
44
45 def pack_diropargs(self, da):
46 dir, name = da
47 self.pack_fhandle(dir)
48 self.pack_string(name)
49
50 def pack_readdirargs(self, ra):
51 dir, cookie, count = ra
52 self.pack_fhandle(dir)
53 self.pack_uint(cookie)
54 self.pack_uint(count)
55
56 def pack_timeval(self, tv):
57 secs, usecs = tv
58 self.pack_uint(secs)
59 self.pack_uint(usecs)
60
61
62class NFSUnpacker(MountUnpacker):
63
64 def unpack_readdirres(self):
65 status = self.unpack_enum()
66 if status == NFS_OK:
67 entries = self.unpack_list(self.unpack_entry)
68 eof = self.unpack_bool()
69 rest = (entries, eof)
70 else:
71 rest = None
72 return (status, rest)
73
74 def unpack_entry(self):
75 fileid = self.unpack_uint()
76 name = self.unpack_string()
77 cookie = self.unpack_uint()
78 return (fileid, name, cookie)
79
80 def unpack_diropres(self):
81 status = self.unpack_enum()
82 if status == NFS_OK:
83 fh = self.unpack_fhandle()
84 fa = self.unpack_fattr()
85 rest = (fh, fa)
86 else:
87 rest = None
88 return (status, rest)
89
90 def unpack_attrstat(self):
91 status = self.unpack_enum()
92 if status == NFS_OK:
93 attributes = self.unpack_fattr()
94 else:
95 attributes = None
96 return status, attributes
97
98 def unpack_fattr(self):
Guido van Rossum4117e541998-09-14 16:44:15 +000099 type = self.unpack_enum()
100 mode = self.unpack_uint()
101 nlink = self.unpack_uint()
102 uid = self.unpack_uint()
103 gid = self.unpack_uint()
104 size = self.unpack_uint()
105 blocksize = self.unpack_uint()
106 rdev = self.unpack_uint()
107 blocks = self.unpack_uint()
108 fsid = self.unpack_uint()
109 fileid = self.unpack_uint()
110 atime = self.unpack_timeval()
111 mtime = self.unpack_timeval()
112 ctime = self.unpack_timeval()
113 return (type, mode, nlink, uid, gid, size, blocksize, \
114 rdev, blocks, fsid, fileid, atime, mtime, ctime)
Guido van Rossume3cafbe1992-12-14 23:25:04 +0000115
116 def unpack_timeval(self):
117 secs = self.unpack_uint()
118 usecs = self.unpack_uint()
119 return (secs, usecs)
120
121
122class NFSClient(UDPClient):
123
Guido van Rossum9e80d6f1993-12-17 14:32:26 +0000124 def __init__(self, host):
125 UDPClient.__init__(self, host, NFS_PROGRAM, NFS_VERSION)
Guido van Rossume3cafbe1992-12-14 23:25:04 +0000126
127 def addpackers(self):
Guido van Rossum9e80d6f1993-12-17 14:32:26 +0000128 self.packer = NFSPacker()
129 self.unpacker = NFSUnpacker('')
Guido van Rossume3cafbe1992-12-14 23:25:04 +0000130
Guido van Rossumb99457c1992-12-20 14:57:51 +0000131 def mkcred(self):
Guido van Rossum195a4f71992-12-15 20:52:31 +0000132 if self.cred == None:
133 self.cred = rpc.AUTH_UNIX, rpc.make_auth_unix_default()
134 return self.cred
135
Guido van Rossume3cafbe1992-12-14 23:25:04 +0000136 def Getattr(self, fh):
Guido van Rossum9ef9c071992-12-21 14:33:05 +0000137 return self.make_call(1, fh, \
138 self.packer.pack_fhandle, \
139 self.unpacker.unpack_attrstat)
Guido van Rossume3cafbe1992-12-14 23:25:04 +0000140
141 def Setattr(self, sa):
Guido van Rossum9ef9c071992-12-21 14:33:05 +0000142 return self.make_call(2, sa, \
143 self.packer.pack_sattrargs, \
144 self.unpacker.unpack_attrstat)
Guido van Rossume3cafbe1992-12-14 23:25:04 +0000145
146 # Root() is obsolete
147
148 def Lookup(self, da):
Guido van Rossum9ef9c071992-12-21 14:33:05 +0000149 return self.make_call(4, da, \
150 self.packer.pack_diropargs, \
151 self.unpacker.unpack_diropres)
Guido van Rossume3cafbe1992-12-14 23:25:04 +0000152
153 # ...
154
155 def Readdir(self, ra):
Guido van Rossum9ef9c071992-12-21 14:33:05 +0000156 return self.make_call(16, ra, \
157 self.packer.pack_readdirargs, \
158 self.unpacker.unpack_readdirres)
Guido van Rossume3cafbe1992-12-14 23:25:04 +0000159
160 # Shorthand to get the entire contents of a directory
161 def Listdir(self, dir):
162 list = []
Guido van Rossumad5f8621992-12-15 21:43:04 +0000163 ra = (dir, 0, 2000)
Guido van Rossume3cafbe1992-12-14 23:25:04 +0000164 while 1:
165 (status, rest) = self.Readdir(ra)
166 if status <> NFS_OK:
167 break
168 entries, eof = rest
169 last_cookie = None
170 for fileid, name, cookie in entries:
Guido van Rossum9c2c1e81998-10-08 15:24:48 +0000171 list.append((fileid, name))
Guido van Rossume3cafbe1992-12-14 23:25:04 +0000172 last_cookie = cookie
Guido van Rossumad5f8621992-12-15 21:43:04 +0000173 if eof or last_cookie == None:
Guido van Rossume3cafbe1992-12-14 23:25:04 +0000174 break
175 ra = (ra[0], last_cookie, ra[2])
176 return list
177
178
179def test():
180 import sys
181 if sys.argv[1:]: host = sys.argv[1]
182 else: host = ''
183 if sys.argv[2:]: filesys = sys.argv[2]
184 else: filesys = None
185 from mountclient import UDPMountClient, TCPMountClient
Guido van Rossum9e80d6f1993-12-17 14:32:26 +0000186 mcl = TCPMountClient(host)
Guido van Rossume3cafbe1992-12-14 23:25:04 +0000187 if filesys == None:
188 list = mcl.Export()
189 for item in list:
190 print item
191 return
192 sf = mcl.Mnt(filesys)
193 print sf
194 fh = sf[1]
195 if fh:
Guido van Rossum9e80d6f1993-12-17 14:32:26 +0000196 ncl = NFSClient(host)
Guido van Rossume3cafbe1992-12-14 23:25:04 +0000197 as = ncl.Getattr(fh)
198 print as
199 list = ncl.Listdir(fh)
200 for item in list: print item
Guido van Rossumad5f8621992-12-15 21:43:04 +0000201 mcl.Umnt(filesys)