138494Sobrien/* 2174294Sobrien * Copyright (c) 1997-2006 Erez Zadok 338494Sobrien * Copyright (c) 1989 Jan-Simon Pendry 438494Sobrien * Copyright (c) 1989 Imperial College of Science, Technology & Medicine 538494Sobrien * Copyright (c) 1989 The Regents of the University of California. 638494Sobrien * All rights reserved. 738494Sobrien * 838494Sobrien * This code is derived from software contributed to Berkeley by 938494Sobrien * Jan-Simon Pendry at Imperial College, London. 1038494Sobrien * 1138494Sobrien * Redistribution and use in source and binary forms, with or without 1238494Sobrien * modification, are permitted provided that the following conditions 1338494Sobrien * are met: 1438494Sobrien * 1. Redistributions of source code must retain the above copyright 1538494Sobrien * notice, this list of conditions and the following disclaimer. 1638494Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1738494Sobrien * notice, this list of conditions and the following disclaimer in the 1838494Sobrien * documentation and/or other materials provided with the distribution. 1938494Sobrien * 3. All advertising materials mentioning features or use of this software 2042629Sobrien * must display the following acknowledgment: 2138494Sobrien * This product includes software developed by the University of 2238494Sobrien * California, Berkeley and its contributors. 2338494Sobrien * 4. Neither the name of the University nor the names of its contributors 2438494Sobrien * may be used to endorse or promote products derived from this software 2538494Sobrien * without specific prior written permission. 2638494Sobrien * 2738494Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2838494Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2938494Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3038494Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3138494Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3238494Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3338494Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3438494Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3538494Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3638494Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3738494Sobrien * SUCH DAMAGE. 3838494Sobrien * 3938494Sobrien * 40174294Sobrien * File: am-utils/hlfsd/stubs.c 4138494Sobrien * 4238494Sobrien * HLFSD was written at Columbia University Computer Science Department, by 4338494Sobrien * Erez Zadok <ezk@cs.columbia.edu> and Alexander Dupuy <dupuy@cs.columbia.edu> 4438494Sobrien * It is being distributed under the same terms and conditions as amd does. 4538494Sobrien */ 4638494Sobrien 4738494Sobrien#ifdef HAVE_CONFIG_H 4838494Sobrien# include <config.h> 4938494Sobrien#endif /* HAVE_CONFIG_H */ 5038494Sobrien#include <am_defs.h> 5138494Sobrien#include <hlfsd.h> 5238494Sobrien 5338494Sobrien/* 5438494Sobrien * STATIC VARIABLES: 5538494Sobrien */ 5638494Sobrienstatic nfsfattr rootfattr = {NFDIR, 0040555, 2, 0, 0, 512, 512, 0, 5738494Sobrien 1, 0, ROOTID}; 5838494Sobrienstatic nfsfattr slinkfattr = {NFLNK, 0120777, 1, 0, 0, NFS_MAXPATHLEN, 512, 0, 5938494Sobrien (NFS_MAXPATHLEN + 1) / 512, 0, SLINKID}; 6038494Sobrien /* user name file attributes */ 6138494Sobrienstatic nfsfattr un_fattr = {NFLNK, 0120777, 1, 0, 0, NFS_MAXPATHLEN, 512, 0, 6238494Sobrien (NFS_MAXPATHLEN + 1) / 512, 0, INVALIDID}; 6338494Sobrienstatic int started; 6438494Sobrienstatic am_nfs_fh slink; 6538494Sobrienstatic am_nfs_fh un_fhandle; 6638494Sobrien 6738494Sobrien/* 6838494Sobrien * GLOBALS: 6938494Sobrien */ 7038494Sobrienam_nfs_fh root; 7138494Sobrienam_nfs_fh *root_fhp = &root; 7238494Sobrien 7338494Sobrien 7438494Sobrien/* initialize NFS file handles for hlfsd */ 7538494Sobrienvoid 7638494Sobrienhlfsd_init_filehandles(void) 7738494Sobrien{ 7838494Sobrien u_int ui; 7938494Sobrien 8038494Sobrien ui = ROOTID; 8138494Sobrien memcpy(root.fh_data, &ui, sizeof(ui)); 8238494Sobrien 8338494Sobrien ui = SLINKID; 8438494Sobrien memcpy(slink.fh_data, &ui, sizeof(ui)); 8538494Sobrien 8638494Sobrien ui = INVALIDID; 8738494Sobrien memcpy(un_fhandle.fh_data, &ui, sizeof(ui)); 8838494Sobrien} 8938494Sobrien 9038494Sobrien 9138494Sobrienvoidp 9238494Sobriennfsproc_null_2_svc(voidp argp, struct svc_req *rqstp) 9338494Sobrien{ 9438494Sobrien static char res; 9538494Sobrien 9638494Sobrien return (voidp) &res; 9738494Sobrien} 9838494Sobrien 9938494Sobrien 10038494Sobrien/* compare if two filehandles are equal */ 10138494Sobrienstatic int 10238494Sobrieneq_fh(const am_nfs_fh *fh1, const am_nfs_fh *fh2) 10338494Sobrien{ 10438494Sobrien return (!memcmp((char *) fh1, (char *) fh2, sizeof(am_nfs_fh))); 10538494Sobrien} 10638494Sobrien 10738494Sobrien 10838494Sobriennfsattrstat * 10938494Sobriennfsproc_getattr_2_svc(am_nfs_fh *argp, struct svc_req *rqstp) 11038494Sobrien{ 11138494Sobrien static nfsattrstat res; 11238494Sobrien uid_t uid = (uid_t) INVALIDID; 11338494Sobrien gid_t gid = (gid_t) INVALIDID; 11438494Sobrien 11538494Sobrien if (!started) { 11638494Sobrien started++; 11738494Sobrien rootfattr.na_ctime = startup; 11838494Sobrien rootfattr.na_mtime = startup; 11938494Sobrien slinkfattr.na_ctime = startup; 12038494Sobrien slinkfattr.na_mtime = startup; 12138494Sobrien un_fattr.na_ctime = startup; 12238494Sobrien un_fattr.na_mtime = startup; 12338494Sobrien } 12438494Sobrien 125119679Smbr if (getcreds(rqstp, &uid, &gid, nfsxprt) < 0) { 126119679Smbr res.ns_status = NFSERR_STALE; 127119679Smbr return &res; 128119679Smbr } 12938494Sobrien if (eq_fh(argp, &root)) { 130174294Sobrien#if 0 131174294Sobrien /* 132174294Sobrien * XXX: increment mtime of parent directory, causes NFS clients to 133174294Sobrien * invalidate their cache for that directory. 134174294Sobrien * Some NFS clients may need this code. 135174294Sobrien */ 136174294Sobrien if (uid != rootfattr.na_uid) { 137174294Sobrien clocktime(&rootfattr.na_mtime); 138174294Sobrien rootfattr.na_uid = uid; 139174294Sobrien } 140174294Sobrien#endif 14138494Sobrien res.ns_status = NFS_OK; 14238494Sobrien res.ns_u.ns_attr_u = rootfattr; 14338494Sobrien } else if (eq_fh(argp, &slink)) { 14438494Sobrien 14538494Sobrien#ifndef MNT2_NFS_OPT_SYMTTL 14638494Sobrien /* 14738494Sobrien * This code is needed to defeat Solaris 2.4's (and newer) symlink 14842629Sobrien * values cache. It forces the last-modified time of the symlink to be 14938494Sobrien * current. It is not needed if the O/S has an nfs flag to turn off the 15038494Sobrien * symlink-cache at mount time (such as Irix 5.x and 6.x). -Erez. 151119679Smbr * 152119679Smbr * Additionally, Linux currently ignores the nt_useconds field, 153119679Smbr * so we must update the nt_seconds field every time. 15438494Sobrien */ 155119679Smbr if (uid != slinkfattr.na_uid) { 156174294Sobrien clocktime(&slinkfattr.na_mtime); 157119679Smbr slinkfattr.na_uid = uid; 158119679Smbr } 15938494Sobrien#endif /* not MNT2_NFS_OPT_SYMTTL */ 16038494Sobrien 16138494Sobrien res.ns_status = NFS_OK; 16238494Sobrien res.ns_u.ns_attr_u = slinkfattr; 16338494Sobrien } else { 16438494Sobrien if (gid != hlfs_gid) { 16538494Sobrien res.ns_status = NFSERR_STALE; 16638494Sobrien } else { 16738494Sobrien memset((char *) &uid, 0, sizeof(int)); 16838494Sobrien uid = *(u_int *) argp->fh_data; 16938494Sobrien if (plt_search(uid) != (uid2home_t *) NULL) { 17038494Sobrien res.ns_status = NFS_OK; 17138494Sobrien un_fattr.na_fileid = uid; 17238494Sobrien res.ns_u.ns_attr_u = un_fattr; 17351292Sobrien dlog("nfs_getattr: successful search for uid=%ld, gid=%ld", 17451292Sobrien (long) uid, (long) gid); 17538494Sobrien } else { /* not found */ 17638494Sobrien res.ns_status = NFSERR_STALE; 17738494Sobrien } 17838494Sobrien } 17938494Sobrien } 18038494Sobrien return &res; 18138494Sobrien} 18238494Sobrien 18338494Sobrien 18438494Sobriennfsattrstat * 18538494Sobriennfsproc_setattr_2_svc(nfssattrargs *argp, struct svc_req *rqstp) 18638494Sobrien{ 18738494Sobrien static nfsattrstat res = {NFSERR_ROFS}; 18838494Sobrien 18938494Sobrien return &res; 19038494Sobrien} 19138494Sobrien 19238494Sobrien 19338494Sobrienvoidp 19438494Sobriennfsproc_root_2_svc(voidp argp, struct svc_req *rqstp) 19538494Sobrien{ 19638494Sobrien static char res; 19738494Sobrien 19838494Sobrien return (voidp) &res; 19938494Sobrien} 20038494Sobrien 20138494Sobrien 20238494Sobriennfsdiropres * 20338494Sobriennfsproc_lookup_2_svc(nfsdiropargs *argp, struct svc_req *rqstp) 20438494Sobrien{ 20538494Sobrien static nfsdiropres res; 20638494Sobrien int idx; 20738494Sobrien uid_t uid = (uid_t) INVALIDID; 20838494Sobrien gid_t gid = (gid_t) INVALIDID; 20938494Sobrien 21038494Sobrien if (!started) { 21138494Sobrien started++; 21238494Sobrien rootfattr.na_ctime = startup; 21338494Sobrien rootfattr.na_mtime = startup; 21438494Sobrien slinkfattr.na_ctime = startup; 21538494Sobrien slinkfattr.na_mtime = startup; 21638494Sobrien un_fattr.na_ctime = startup; 21738494Sobrien un_fattr.na_mtime = startup; 21838494Sobrien } 21938494Sobrien 22038494Sobrien if (eq_fh(&argp->da_fhandle, &slink)) { 22138494Sobrien res.dr_status = NFSERR_NOTDIR; 22238494Sobrien return &res; 22338494Sobrien } 22438494Sobrien 225119679Smbr if (getcreds(rqstp, &uid, &gid, nfsxprt) < 0) { 226119679Smbr res.dr_status = NFSERR_NOENT; 227119679Smbr return &res; 228119679Smbr } 22938494Sobrien if (eq_fh(&argp->da_fhandle, &root)) { 23038494Sobrien if (argp->da_name[0] == '.' && 23138494Sobrien (argp->da_name[1] == '\0' || 23238494Sobrien (argp->da_name[1] == '.' && 23338494Sobrien argp->da_name[2] == '\0'))) { 234174294Sobrien#if 0 235174294Sobrien /* 236174294Sobrien * XXX: increment mtime of parent directory, causes NFS clients to 237174294Sobrien * invalidate their cache for that directory. 238174294Sobrien * Some NFS clients may need this code. 239174294Sobrien */ 240174294Sobrien if (uid != rootfattr.na_uid) { 241174294Sobrien clocktime(&rootfattr.na_mtime); 242174294Sobrien rootfattr.na_uid = uid; 243174294Sobrien } 244174294Sobrien#endif 24538494Sobrien res.dr_u.dr_drok_u.drok_fhandle = root; 24638494Sobrien res.dr_u.dr_drok_u.drok_attributes = rootfattr; 24738494Sobrien res.dr_status = NFS_OK; 24838494Sobrien return &res; 24938494Sobrien } 25038494Sobrien 25138494Sobrien if (STREQ(argp->da_name, slinkname)) { 25282794Sobrien#ifndef MNT2_NFS_OPT_SYMTTL 25382794Sobrien /* 25482794Sobrien * This code is needed to defeat Solaris 2.4's (and newer) symlink 25582794Sobrien * values cache. It forces the last-modified time of the symlink to be 25682794Sobrien * current. It is not needed if the O/S has an nfs flag to turn off the 25782794Sobrien * symlink-cache at mount time (such as Irix 5.x and 6.x). -Erez. 258119679Smbr * 259119679Smbr * Additionally, Linux currently ignores the nt_useconds field, 260119679Smbr * so we must update the nt_seconds field every time. 26182794Sobrien */ 262119679Smbr if (uid != slinkfattr.na_uid) { 263174294Sobrien clocktime(&slinkfattr.na_mtime); 264119679Smbr slinkfattr.na_uid = uid; 265119679Smbr } 26682794Sobrien#endif /* not MNT2_NFS_OPT_SYMTTL */ 26738494Sobrien res.dr_u.dr_drok_u.drok_fhandle = slink; 26838494Sobrien res.dr_u.dr_drok_u.drok_attributes = slinkfattr; 26938494Sobrien res.dr_status = NFS_OK; 27038494Sobrien return &res; 27138494Sobrien } 27238494Sobrien 273119679Smbr if (gid != hlfs_gid) { 27438494Sobrien res.dr_status = NFSERR_NOENT; 27538494Sobrien return &res; 27638494Sobrien } 27738494Sobrien 27842629Sobrien /* if gets here, gid == hlfs_gid */ 27938494Sobrien if ((idx = untab_index(argp->da_name)) < 0) { 28038494Sobrien res.dr_status = NFSERR_NOENT; 28138494Sobrien return &res; 28238494Sobrien } else { /* entry found and gid is permitted */ 28338494Sobrien un_fattr.na_fileid = untab[idx].uid; 28438494Sobrien res.dr_u.dr_drok_u.drok_attributes = un_fattr; 28538494Sobrien memset((char *) &un_fhandle, 0, sizeof(am_nfs_fh)); 28638494Sobrien *(u_int *) un_fhandle.fh_data = (u_int) untab[idx].uid; 287174294Sobrien xstrlcpy((char *) &un_fhandle.fh_data[sizeof(int)], 288174294Sobrien untab[idx].username, 289174294Sobrien sizeof(am_nfs_fh) - sizeof(int)); 29038494Sobrien res.dr_u.dr_drok_u.drok_fhandle = un_fhandle; 29138494Sobrien res.dr_status = NFS_OK; 29251292Sobrien dlog("nfs_lookup: successful lookup for uid=%ld, gid=%ld: username=%s", 29351292Sobrien (long) uid, (long) gid, untab[idx].username); 29438494Sobrien return &res; 29538494Sobrien } 29638494Sobrien } /* end of "if (eq_fh(argp->dir.data, root.data)) {" */ 29738494Sobrien 29838494Sobrien res.dr_status = NFSERR_STALE; 29938494Sobrien return &res; 30038494Sobrien} 30138494Sobrien 30238494Sobrien 30338494Sobriennfsreadlinkres * 30438494Sobriennfsproc_readlink_2_svc(am_nfs_fh *argp, struct svc_req *rqstp) 30538494Sobrien{ 30638494Sobrien static nfsreadlinkres res; 30738494Sobrien uid_t userid = (uid_t) INVALIDID; 30838494Sobrien gid_t groupid = hlfs_gid + 1; /* anything not hlfs_gid */ 30938494Sobrien int retval = 0; 31038494Sobrien char *path_val = (char *) NULL; 31138494Sobrien char *username; 31238494Sobrien static uid_t last_uid = (uid_t) INVALIDID; 31338494Sobrien 31438494Sobrien if (eq_fh(argp, &root)) { 31538494Sobrien res.rlr_status = NFSERR_ISDIR; 31638494Sobrien } else if (eq_fh(argp, &slink)) { 31782794Sobrien if (getcreds(rqstp, &userid, &groupid, nfsxprt) < 0) 31838494Sobrien return (nfsreadlinkres *) NULL; 31938494Sobrien 320174294Sobrien clocktime(&slinkfattr.na_atime); 32138494Sobrien 32238494Sobrien res.rlr_status = NFS_OK; 32338494Sobrien if (groupid == hlfs_gid) { 32438494Sobrien res.rlr_u.rlr_data_u = DOTSTRING; 325119679Smbr } else if (!(res.rlr_u.rlr_data_u = path_val = homedir(userid, groupid))) { 32638494Sobrien /* 32738494Sobrien * parent process (fork in homedir()) continues 32838494Sobrien * processing, by getting a NULL returned as a 32938494Sobrien * "special". Child returns result. 33038494Sobrien */ 33138494Sobrien return (nfsreadlinkres *) NULL; 33238494Sobrien } 33338494Sobrien 33438494Sobrien } else { /* check if asked for user mailbox */ 33538494Sobrien 33682794Sobrien if (getcreds(rqstp, &userid, &groupid, nfsxprt) < 0) { 33738494Sobrien return (nfsreadlinkres *) NULL; 33838494Sobrien } 33938494Sobrien 34038494Sobrien if (groupid == hlfs_gid) { 34138494Sobrien memset((char *) &userid, 0, sizeof(int)); 34238494Sobrien userid = *(u_int *) argp->fh_data; 34338494Sobrien username = (char *) &argp->fh_data[sizeof(int)]; 34438494Sobrien if (!(res.rlr_u.rlr_data_u = mailbox(userid, username))) 34538494Sobrien return (nfsreadlinkres *) NULL; 34638494Sobrien } else { 34738494Sobrien res.rlr_status = NFSERR_STALE; 34838494Sobrien } 34938494Sobrien } 35038494Sobrien 35138494Sobrien /* print info, but try to avoid repetitions */ 35238494Sobrien if (userid != last_uid) { 35351292Sobrien plog(XLOG_USER, "mailbox for uid=%ld, gid=%ld is %s", 35451292Sobrien (long) userid, (long) groupid, (char *) res.rlr_u.rlr_data_u); 35538494Sobrien last_uid = userid; 35638494Sobrien } 35738494Sobrien 358174294Sobrien /* I don't think it will pass this if -D fork */ 35938494Sobrien if (serverpid == getpid()) 36038494Sobrien return &res; 36138494Sobrien 36238494Sobrien if (!svc_sendreply(nfsxprt, (XDRPROC_T_TYPE) xdr_readlinkres, (SVC_IN_ARG_TYPE) &res)) 36338494Sobrien svcerr_systemerr(nfsxprt); 36438494Sobrien 36538494Sobrien /* 36638494Sobrien * Child exists here. We need to determine which 36738494Sobrien * exist status to return. The exit status 36838494Sobrien * is gathered using wait() and determines 36938494Sobrien * if we returned $HOME/.hlfsspool or $ALTDIR. The parent 37038494Sobrien * needs this info so it can update the lookup table. 37138494Sobrien */ 37238494Sobrien if (path_val && alt_spooldir && STREQ(path_val, alt_spooldir)) 37338494Sobrien retval = 1; /* could not get real home dir (or uid 0 user) */ 37438494Sobrien else 37538494Sobrien retval = 0; 37638494Sobrien 37738494Sobrien /* 378174294Sobrien * If asked for -D fork, then must return the value, 37938494Sobrien * NOT exit, or else the main hlfsd server exits. 380174294Sobrien * Bug: where is that status information being collected? 38138494Sobrien */ 382174294Sobrien if (amuDebug(D_FORK)) 38338494Sobrien return &res; 38438494Sobrien 38538494Sobrien exit(retval); 38638494Sobrien} 38738494Sobrien 38838494Sobrien 38938494Sobriennfsreadres * 39038494Sobriennfsproc_read_2_svc(nfsreadargs *argp, struct svc_req *rqstp) 39138494Sobrien{ 39238494Sobrien static nfsreadres res = {NFSERR_ACCES}; 39338494Sobrien 39438494Sobrien return &res; 39538494Sobrien} 39638494Sobrien 39738494Sobrien 39838494Sobrienvoidp 39938494Sobriennfsproc_writecache_2_svc(voidp argp, struct svc_req *rqstp) 40038494Sobrien{ 40138494Sobrien static char res; 40238494Sobrien 40338494Sobrien return (voidp) &res; 40438494Sobrien} 40538494Sobrien 40638494Sobrien 40738494Sobriennfsattrstat * 40838494Sobriennfsproc_write_2_svc(nfswriteargs *argp, struct svc_req *rqstp) 40938494Sobrien{ 41038494Sobrien static nfsattrstat res = {NFSERR_ROFS}; 41138494Sobrien 41238494Sobrien return &res; 41338494Sobrien} 41438494Sobrien 41538494Sobrien 41638494Sobriennfsdiropres * 41738494Sobriennfsproc_create_2_svc(nfscreateargs *argp, struct svc_req *rqstp) 41838494Sobrien{ 41938494Sobrien static nfsdiropres res = {NFSERR_ROFS}; 42038494Sobrien 42138494Sobrien return &res; 42238494Sobrien} 42338494Sobrien 42438494Sobrien 42538494Sobriennfsstat * 42638494Sobriennfsproc_remove_2_svc(nfsdiropargs *argp, struct svc_req *rqstp) 42738494Sobrien{ 42838494Sobrien static nfsstat res = {NFSERR_ROFS}; 42938494Sobrien 43038494Sobrien return &res; 43138494Sobrien} 43238494Sobrien 43338494Sobrien 43438494Sobriennfsstat * 43538494Sobriennfsproc_rename_2_svc(nfsrenameargs *argp, struct svc_req *rqstp) 43638494Sobrien{ 43738494Sobrien static nfsstat res = {NFSERR_ROFS}; 43838494Sobrien 43938494Sobrien return &res; 44038494Sobrien} 44138494Sobrien 44238494Sobrien 44338494Sobriennfsstat * 44438494Sobriennfsproc_link_2_svc(nfslinkargs *argp, struct svc_req *rqstp) 44538494Sobrien{ 44638494Sobrien static nfsstat res = {NFSERR_ROFS}; 44738494Sobrien 44838494Sobrien return &res; 44938494Sobrien} 45038494Sobrien 45138494Sobrien 45238494Sobriennfsstat * 45338494Sobriennfsproc_symlink_2_svc(nfssymlinkargs *argp, struct svc_req *rqstp) 45438494Sobrien{ 45538494Sobrien static nfsstat res = {NFSERR_ROFS}; 45638494Sobrien 45738494Sobrien return &res; 45838494Sobrien} 45938494Sobrien 46038494Sobrien 46138494Sobriennfsdiropres * 46238494Sobriennfsproc_mkdir_2_svc(nfscreateargs *argp, struct svc_req *rqstp) 46338494Sobrien{ 46438494Sobrien static nfsdiropres res = {NFSERR_ROFS}; 46538494Sobrien 46638494Sobrien return &res; 46738494Sobrien} 46838494Sobrien 46938494Sobrien 47038494Sobriennfsstat * 47138494Sobriennfsproc_rmdir_2_svc(nfsdiropargs *argp, struct svc_req *rqstp) 47238494Sobrien{ 47338494Sobrien static nfsstat res = {NFSERR_ROFS}; 47438494Sobrien 47538494Sobrien return &res; 47638494Sobrien} 47738494Sobrien 47838494Sobrien 47938494Sobriennfsreaddirres * 48038494Sobriennfsproc_readdir_2_svc(nfsreaddirargs *argp, struct svc_req *rqstp) 48138494Sobrien{ 48238494Sobrien static nfsreaddirres res; 48338494Sobrien static nfsentry slinkent = {SLINKID, 0, {SLINKCOOKIE}}; 48438494Sobrien static nfsentry dotdotent = {ROOTID, "..", {DOTDOTCOOKIE}, &slinkent}; 48538494Sobrien static nfsentry dotent = {ROOTID, ".", {DOTCOOKIE}, &dotdotent}; 48638494Sobrien 48738494Sobrien slinkent.ne_name = slinkname; 48838494Sobrien 48938494Sobrien if (eq_fh(&argp->rda_fhandle, &slink)) { 49038494Sobrien res.rdr_status = NFSERR_NOTDIR; 49138494Sobrien } else if (eq_fh(&argp->rda_fhandle, &root)) { 492174294Sobrien clocktime(&rootfattr.na_atime); 49338494Sobrien 49438494Sobrien res.rdr_status = NFS_OK; 49538494Sobrien switch (argp->rda_cookie[0]) { 49638494Sobrien case 0: 49738494Sobrien res.rdr_u.rdr_reply_u.dl_entries = &dotent; 49838494Sobrien break; 49938494Sobrien case DOTCOOKIE: 50038494Sobrien res.rdr_u.rdr_reply_u.dl_entries = &dotdotent; 50138494Sobrien break; 50238494Sobrien case DOTDOTCOOKIE: 50338494Sobrien res.rdr_u.rdr_reply_u.dl_entries = &slinkent; 50438494Sobrien break; 50538494Sobrien case SLINKCOOKIE: 50638494Sobrien res.rdr_u.rdr_reply_u.dl_entries = (nfsentry *) 0; 50738494Sobrien break; 50838494Sobrien } 50938494Sobrien res.rdr_u.rdr_reply_u.dl_eof = TRUE; 51038494Sobrien } else { 51138494Sobrien res.rdr_status = NFSERR_STALE; 51238494Sobrien } 51338494Sobrien return &res; 51438494Sobrien} 51538494Sobrien 51638494Sobrien 51738494Sobriennfsstatfsres * 51838494Sobriennfsproc_statfs_2_svc(am_nfs_fh *argp, struct svc_req *rqstp) 51938494Sobrien{ 52038494Sobrien static nfsstatfsres res = {NFS_OK}; 52138494Sobrien 52238494Sobrien res.sfr_u.sfr_reply_u.sfrok_tsize = 1024; 52338494Sobrien res.sfr_u.sfr_reply_u.sfrok_bsize = 1024; 52438494Sobrien 52538494Sobrien /* 52638494Sobrien * Some "df" programs automatically assume that file systems 52738494Sobrien * with zero blocks are meta-filesystems served by automounters. 52838494Sobrien */ 52938494Sobrien res.sfr_u.sfr_reply_u.sfrok_blocks = 0; 53038494Sobrien res.sfr_u.sfr_reply_u.sfrok_bfree = 0; 53138494Sobrien res.sfr_u.sfr_reply_u.sfrok_bavail = 0; 53238494Sobrien 53338494Sobrien return &res; 53438494Sobrien} 535