2 * Simple read-only NFS v3 server.
3 * Runs every request in its own thread.
4 * Expects client to provide the fsxxx routines in nfs3srv.h.
16 authunixunpack(SunRpc *rpc, SunAuthUnix *au)
22 if(ai->flavor != SunAuthSys)
23 return SunAuthTooWeak;
26 if(sunauthunixunpack(p, ep, &p, au) < 0)
27 return SunGarbageArgs;
43 memset(&rx, 0, sizeof rx);
44 return sunmsgreply(m, &rx.call);
55 if((ok = authunixunpack(&m->rpc, &au)) != SunSuccess)
56 return sunmsgreplyerror(m, ok);
58 /* ignore file system path and return the dump tree */
60 memset(&rx, 0, sizeof rx);
63 memset(&nh, 0, sizeof nh);
68 return sunmsgreply(m, &rx.call);
78 memset(&rx, 0, sizeof rx);
79 return sunmsgreply(m, &rx.call);
89 memset(&rx, 0, sizeof rx);
90 return sunmsgreply(m, &rx.call);
100 memset(&rx, 0, sizeof rx);
102 return sunmsgreply(m, &rx.call);
111 switch(m->call->type){
113 sunmsgreplyerror(m, SunProcUnavail);
114 case NfsMount3CallTNull:
117 case NfsMount3CallTMnt:
120 case NfsMount3CallTDump:
123 case NfsMount3CallTUmnt:
126 case NfsMount3CallTUmntall:
129 case NfsMount3CallTExport:
141 threadsetname("mount1");
143 while((m=recvp(c)) != nil)
144 threadcreate(rmount3, m, SunStackSize);
148 senderror(SunMsg *m, SunCall *rc, Nfs3Status status)
150 /* knows that status is first field in all replies */
151 ((Nfs3RGetattr*)rc)->status = status;
152 return sunmsgreply(m, rc);
160 memset(&rx, 0, sizeof rx);
161 return sunmsgreply(m, &rx.call);
167 Nfs3TGetattr *tx = (Nfs3TGetattr*)m->call;
172 if((ok = authunixunpack(&m->rpc, &au)) != SunSuccess)
173 return sunmsgreplyerror(m, ok);
175 memset(&rx, 0, sizeof rx);
176 rx.status = fsgetattr(&au, &tx->handle, &rx.attr);
177 return sunmsgreply(m, &rx.call);
183 Nfs3TLookup *tx = (Nfs3TLookup*)m->call;
188 if((ok = authunixunpack(&m->rpc, &au)) != SunSuccess)
189 return sunmsgreplyerror(m, ok);
191 memset(&rx, 0, sizeof rx);
192 rx.status = fsgetattr(&au, &tx->handle, &rx.dirAttr);
193 if(rx.status != Nfs3Ok)
194 return sunmsgreply(m, &rx.call);
196 rx.status = fslookup(&au, &tx->handle, tx->name, &rx.handle);
197 if(rx.status != Nfs3Ok)
198 return sunmsgreply(m, &rx.call);
199 rx.status = fsgetattr(&au, &rx.handle, &rx.attr);
200 if(rx.status != Nfs3Ok)
201 return sunmsgreply(m, &rx.call);
203 return sunmsgreply(m, &rx.call);
209 Nfs3TAccess *tx = (Nfs3TAccess*)m->call;
214 if((ok = authunixunpack(&m->rpc, &au)) != SunSuccess)
215 return sunmsgreplyerror(m, ok);
217 memset(&rx, 0, sizeof rx);
219 rx.status = fsaccess(&au, &tx->handle, tx->access, &rx.access, &rx.attr);
220 return sunmsgreply(m, &rx.call);
227 Nfs3TReadlink *tx = (Nfs3TReadlink*)m->call;
231 if((ok = authunixunpack(&m->rpc, &au)) != SunSuccess)
232 return sunmsgreplyerror(m, ok);
234 memset(&rx, 0, sizeof rx);
237 rx.status = fsreadlink(&au, &tx->handle, &rx.data);
238 sunmsgreply(m, &rx.call);
246 Nfs3TRead *tx = (Nfs3TRead*)m->call;
251 if((ok = authunixunpack(&m->rpc, &au)) != SunSuccess)
252 return sunmsgreplyerror(m, ok);
254 memset(&rx, 0, sizeof rx);
257 rx.status = fsreadfile(&au, &tx->handle, tx->count, tx->offset, &rx.data, &rx.count, &rx.eof);
258 if(rx.status == Nfs3Ok)
261 sunmsgreply(m, &rx.call);
269 Nfs3TReadDir *tx = (Nfs3TReadDir*)m->call;
274 if((ok = authunixunpack(&m->rpc, &au)) != SunSuccess)
275 return sunmsgreplyerror(m, ok);
277 memset(&rx, 0, sizeof rx);
278 rx.status = fsreaddir(&au, &tx->handle, tx->count, tx->cookie, &rx.data, &rx.count, &rx.eof);
279 sunmsgreply(m, &rx.call);
285 rreaddirplus(SunMsg *m)
289 memset(&rx, 0, sizeof rx);
290 rx.status = Nfs3ErrNotSupp;
291 sunmsgreply(m, &rx.call);
300 /* just make something up */
301 memset(&rx, 0, sizeof rx);
304 rx.totalBytes = 1000000000;
307 rx.totalFiles = 100000;
311 return sunmsgreply(m, &rx.call);
319 /* just make something up */
320 memset(&rx, 0, sizeof rx);
323 rx.readMax = MaxDataSize;
324 rx.readPref = MaxDataSize;
325 rx.readMult = MaxDataSize;
326 rx.writeMax = MaxDataSize;
327 rx.writePref = MaxDataSize;
328 rx.writeMult = MaxDataSize;
329 rx.readDirPref = MaxDataSize;
330 rx.maxFileSize = 1LL<<60;
332 rx.timePrec.nsec = 0;
333 rx.flags = Nfs3FsHomogeneous|Nfs3FsCanSetTime;
334 return sunmsgreply(m, &rx.call);
342 memset(&rx, 0, sizeof rx);
348 rx.chownRestricted = 0;
349 rx.caseInsensitive = 0;
350 rx.casePreserving = 1;
351 return sunmsgreply(m, &rx.call);
357 uchar buf[512]; /* clumsy hack*/
359 memset(buf, 0, sizeof buf);
360 return senderror(m, (SunCall*)buf, Nfs3ErrRoFs);
370 switch(m->call->type){
376 case Nfs3CallTGetattr:
379 case Nfs3CallTLookup:
382 case Nfs3CallTAccess:
385 case Nfs3CallTReadlink:
391 case Nfs3CallTReadDir:
394 case Nfs3CallTReadDirPlus:
397 case Nfs3CallTFsStat:
400 case Nfs3CallTFsInfo:
403 case Nfs3CallTPathconf:
406 case Nfs3CallTSetattr:
408 case Nfs3CallTCreate:
410 case Nfs3CallTSymlink:
412 case Nfs3CallTRemove:
415 case Nfs3CallTCommit:
428 threadsetname("nfs3");
429 while((m = recvp(c)) != nil)
430 threadcreate(rnfs3, m, SunStackSize);