]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/python/Demo/rpc/nfsclient.py
/sys/lib/dist/mkfile: test for .git directory
[plan9front.git] / sys / src / cmd / python / Demo / rpc / nfsclient.py
1 # NFS RPC client -- RFC 1094
2
3 # XXX This is not yet complete.
4 # XXX Only GETATTR, SETTTR, LOOKUP and READDIR are supported.
5
6 # (See mountclient.py for some hints on how to write RPC clients in
7 # Python in general)
8
9 import rpc
10 from rpc import UDPClient, TCPClient
11 from mountclient import FHSIZE, MountPacker, MountUnpacker
12
13 NFS_PROGRAM = 100003
14 NFS_VERSION = 2
15
16 # enum stat
17 NFS_OK = 0
18 # (...many error values...)
19
20 # enum ftype
21 NFNON = 0
22 NFREG = 1
23 NFDIR = 2
24 NFBLK = 3
25 NFCHR = 4
26 NFLNK = 5
27
28
29 class 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
62 class 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):
99         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)
115
116     def unpack_timeval(self):
117         secs = self.unpack_uint()
118         usecs = self.unpack_uint()
119         return (secs, usecs)
120
121
122 class NFSClient(UDPClient):
123
124     def __init__(self, host):
125         UDPClient.__init__(self, host, NFS_PROGRAM, NFS_VERSION)
126
127     def addpackers(self):
128         self.packer = NFSPacker()
129         self.unpacker = NFSUnpacker('')
130
131     def mkcred(self):
132         if self.cred == None:
133             self.cred = rpc.AUTH_UNIX, rpc.make_auth_unix_default()
134         return self.cred
135
136     def Getattr(self, fh):
137         return self.make_call(1, fh, \
138                 self.packer.pack_fhandle, \
139                 self.unpacker.unpack_attrstat)
140
141     def Setattr(self, sa):
142         return self.make_call(2, sa, \
143                 self.packer.pack_sattrargs, \
144                 self.unpacker.unpack_attrstat)
145
146     # Root() is obsolete
147
148     def Lookup(self, da):
149         return self.make_call(4, da, \
150                 self.packer.pack_diropargs, \
151                 self.unpacker.unpack_diropres)
152
153     # ...
154
155     def Readdir(self, ra):
156         return self.make_call(16, ra, \
157                 self.packer.pack_readdirargs, \
158                 self.unpacker.unpack_readdirres)
159
160     # Shorthand to get the entire contents of a directory
161     def Listdir(self, dir):
162         list = []
163         ra = (dir, 0, 2000)
164         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:
171                 list.append((fileid, name))
172                 last_cookie = cookie
173             if eof or last_cookie == None:
174                 break
175             ra = (ra[0], last_cookie, ra[2])
176         return list
177
178
179 def 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
186     mcl = TCPMountClient(host)
187     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:
196         ncl = NFSClient(host)
197         as = ncl.Getattr(fh)
198         print as
199         list = ncl.Listdir(fh)
200         for item in list: print item
201         mcl.Umnt(filesys)