/* $Id: server.C,v 1.73 2000/10/09 04:50:40 dm Exp $ */ /* * * Copyright (C) 1998-2000 David Mazieres (dm@uun.org) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * */ #include "sfsrwcd.h" #include "axprt_crypt.h" /* #define NO_ACACHE 1 */ void server::getreply (time_t rqtime, nfscall *nc, void *res, clnt_stat err) { auto_xdr_delete axd (ex_nfs_program_3.tbl[nc->proc ()].xdr_res, res); if (err) { if (err == RPC_CANTSEND || err == RPC_CANTRECV) getnfscall (nc); else nc->reject (SYSTEM_ERR); return; } #ifndef NO_ACACHE xattrvec xv; nfs3_getxattr (&xv, nc->proc (), nc->getvoidarg (), res); for (xattr *x = xv.base (); x < xv.lim (); x++) { if (x->fattr) x->fattr->expire += rqtime; ac.attr_enter (*x->fh, x->fattr, x->wattr); if (nc->proc () == NFSPROC3_ACCESS) { ex_access3res *ares = static_cast (res); access3args *a = nc->template getarg (); if (ares->status) ac.flush_access (a->object, nc->getaid ()); else ac.access_enter (a->object, nc->getaid (), a->access, ares->resok->access); } } #endif /* !NO_ACACHE */ nfs3_exp_disable (nc->proc (), res); nc->reply (res); } void server::cbdispatch (svccb *sbp) { if (!sbp) return; switch (sbp->proc ()) { case ex_NFSCBPROC3_NULL: sbp->reply (NULL); break; case ex_NFSCBPROC3_INVALIDATE: { ex_invalidate3args *xa = sbp->template getarg (); ex_fattr3 *a = NULL; if (xa->attributes.present && xa->attributes.attributes->expire) { a = xa->attributes.attributes.addr (); a->expire += timenow; } ac.attr_enter (xa->handle, a, NULL); sbp->reply (NULL); break; } default: sbp->reject (PROC_UNAVAIL); break; } } void server::flushstate () { ac.flush_attr (); nfsc = NULL; nfscbs = NULL; super::flushstate (); } void server::authclear (sfs_aid aid) { ac.flush_access (aid); super::authclear (aid); } bool server::setrootfh (const sfs_fsinfo *fsi) { if (fsi->prog != ex_NFS_PROGRAM || fsi->nfs->vers != ex_NFS_V3) return false; nfs_fh3 fh (fsi->nfs->v3->root); if (fsinfo && rootfh.data != fh.data) return false; rootfh = fh; nfsc = aclnt::alloc (x, ex_nfs_program_3); nfscbs = asrv::alloc (x, ex_nfscb_program_3, wrap (this, &server::cbdispatch)); return true; } void server::dispatch (nfscall *nc) { #if 0 if (sfsctl_intercept (this, srvno, nc)) return; #endif #if 0 if (nc->proc () == NFSPROC_CLOSE) { nfs_fh3 *fhp = nc->getfh3arg (); warn << "close 0x" << hexdump (fhp->data.base (), fhp->data.size ()) << "\n"; nfsstat3 ok (NFS3_OK); nc->reply (&ok); return; } #endif #ifndef NO_ACACHE if (nc->proc () == NFSPROC3_GETATTR) { const ex_fattr3 *f = ac.attr_lookup (*nc->template getarg ()); if (f) { getattr3res res (NFS3_OK); *res.attributes = *reinterpret_cast (f); nc->reply (&res); return; } } else if (nc->proc () == NFSPROC3_ACCESS) { access3args *a = nc->template getarg (); int32_t perm = ac.access_lookup (a->object, nc->getaid (), a->access); if (perm > 0) { access3res res (NFS3_OK); res.resok->obj_attributes.set_present (true); *res.resok->obj_attributes.attributes = *reinterpret_cast (ac.attr_lookup (a->object)); res.resok->access = perm; nc->reply (&res); return; } } #endif /* !NO_ACACHE */ void *res = ex_nfs_program_3.tbl[nc->proc ()].alloc_res (); nfsc->call (nc->proc (), nc->getvoidarg (), res, wrap (mkref (this), &server::getreply, timenow, nc, res), authof (nc->getaid ())); }