138494Sobrien/* 2310490Scy * Copyright (c) 1997-2014 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. 19310490Scy * 3. Neither the name of the University nor the names of its contributors 2038494Sobrien * may be used to endorse or promote products derived from this software 2138494Sobrien * without specific prior written permission. 2238494Sobrien * 2338494Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2438494Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2538494Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2638494Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2738494Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2838494Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2938494Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3038494Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3138494Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3238494Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3338494Sobrien * SUCH DAMAGE. 3438494Sobrien * 3538494Sobrien * 36174294Sobrien * File: am-utils/hlfsd/stubs.c 3738494Sobrien * 3838494Sobrien * HLFSD was written at Columbia University Computer Science Department, by 3938494Sobrien * Erez Zadok <ezk@cs.columbia.edu> and Alexander Dupuy <dupuy@cs.columbia.edu> 4038494Sobrien * It is being distributed under the same terms and conditions as amd does. 4138494Sobrien */ 4238494Sobrien 4338494Sobrien#ifdef HAVE_CONFIG_H 4438494Sobrien# include <config.h> 4538494Sobrien#endif /* HAVE_CONFIG_H */ 4638494Sobrien#include <am_defs.h> 4738494Sobrien#include <hlfsd.h> 4838494Sobrien 4938494Sobrien/* 5038494Sobrien * STATIC VARIABLES: 5138494Sobrien */ 5238494Sobrienstatic nfsfattr rootfattr = {NFDIR, 0040555, 2, 0, 0, 512, 512, 0, 5338494Sobrien 1, 0, ROOTID}; 5438494Sobrienstatic nfsfattr slinkfattr = {NFLNK, 0120777, 1, 0, 0, NFS_MAXPATHLEN, 512, 0, 5538494Sobrien (NFS_MAXPATHLEN + 1) / 512, 0, SLINKID}; 5638494Sobrien /* user name file attributes */ 5738494Sobrienstatic nfsfattr un_fattr = {NFLNK, 0120777, 1, 0, 0, NFS_MAXPATHLEN, 512, 0, 5838494Sobrien (NFS_MAXPATHLEN + 1) / 512, 0, INVALIDID}; 5938494Sobrienstatic int started; 6038494Sobrienstatic am_nfs_fh slink; 6138494Sobrienstatic am_nfs_fh un_fhandle; 6238494Sobrien 6338494Sobrien/* 6438494Sobrien * GLOBALS: 6538494Sobrien */ 6638494Sobrienam_nfs_fh root; 6738494Sobrienam_nfs_fh *root_fhp = &root; 6838494Sobrien 6938494Sobrien 7038494Sobrien/* initialize NFS file handles for hlfsd */ 7138494Sobrienvoid 7238494Sobrienhlfsd_init_filehandles(void) 7338494Sobrien{ 7438494Sobrien u_int ui; 7538494Sobrien 7638494Sobrien ui = ROOTID; 7738494Sobrien memcpy(root.fh_data, &ui, sizeof(ui)); 7838494Sobrien 7938494Sobrien ui = SLINKID; 8038494Sobrien memcpy(slink.fh_data, &ui, sizeof(ui)); 8138494Sobrien 8238494Sobrien ui = INVALIDID; 8338494Sobrien memcpy(un_fhandle.fh_data, &ui, sizeof(ui)); 8438494Sobrien} 8538494Sobrien 8638494Sobrien 8738494Sobrienvoidp 8838494Sobriennfsproc_null_2_svc(voidp argp, struct svc_req *rqstp) 8938494Sobrien{ 9038494Sobrien static char res; 9138494Sobrien 9238494Sobrien return (voidp) &res; 9338494Sobrien} 9438494Sobrien 9538494Sobrien 9638494Sobrien/* compare if two filehandles are equal */ 9738494Sobrienstatic int 9838494Sobrieneq_fh(const am_nfs_fh *fh1, const am_nfs_fh *fh2) 9938494Sobrien{ 10038494Sobrien return (!memcmp((char *) fh1, (char *) fh2, sizeof(am_nfs_fh))); 10138494Sobrien} 10238494Sobrien 10338494Sobrien 10438494Sobriennfsattrstat * 10538494Sobriennfsproc_getattr_2_svc(am_nfs_fh *argp, struct svc_req *rqstp) 10638494Sobrien{ 10738494Sobrien static nfsattrstat res; 10838494Sobrien uid_t uid = (uid_t) INVALIDID; 10938494Sobrien gid_t gid = (gid_t) INVALIDID; 11038494Sobrien 11138494Sobrien if (!started) { 11238494Sobrien started++; 11338494Sobrien rootfattr.na_ctime = startup; 11438494Sobrien rootfattr.na_mtime = startup; 11538494Sobrien slinkfattr.na_ctime = startup; 11638494Sobrien slinkfattr.na_mtime = startup; 11738494Sobrien un_fattr.na_ctime = startup; 11838494Sobrien un_fattr.na_mtime = startup; 11938494Sobrien } 12038494Sobrien 121119679Smbr if (getcreds(rqstp, &uid, &gid, nfsxprt) < 0) { 122119679Smbr res.ns_status = NFSERR_STALE; 123119679Smbr return &res; 124119679Smbr } 12538494Sobrien if (eq_fh(argp, &root)) { 126174294Sobrien#if 0 127174294Sobrien /* 128174294Sobrien * XXX: increment mtime of parent directory, causes NFS clients to 129174294Sobrien * invalidate their cache for that directory. 130174294Sobrien * Some NFS clients may need this code. 131174294Sobrien */ 132174294Sobrien if (uid != rootfattr.na_uid) { 133174294Sobrien clocktime(&rootfattr.na_mtime); 134174294Sobrien rootfattr.na_uid = uid; 135174294Sobrien } 136310490Scy#endif /* 0 */ 13738494Sobrien res.ns_status = NFS_OK; 13838494Sobrien res.ns_u.ns_attr_u = rootfattr; 13938494Sobrien } else if (eq_fh(argp, &slink)) { 14038494Sobrien 14138494Sobrien#ifndef MNT2_NFS_OPT_SYMTTL 14238494Sobrien /* 14338494Sobrien * This code is needed to defeat Solaris 2.4's (and newer) symlink 14442629Sobrien * values cache. It forces the last-modified time of the symlink to be 14538494Sobrien * current. It is not needed if the O/S has an nfs flag to turn off the 14638494Sobrien * symlink-cache at mount time (such as Irix 5.x and 6.x). -Erez. 147119679Smbr * 148119679Smbr * Additionally, Linux currently ignores the nt_useconds field, 149119679Smbr * so we must update the nt_seconds field every time. 15038494Sobrien */ 151119679Smbr if (uid != slinkfattr.na_uid) { 152174294Sobrien clocktime(&slinkfattr.na_mtime); 153119679Smbr slinkfattr.na_uid = uid; 154119679Smbr } 15538494Sobrien#endif /* not MNT2_NFS_OPT_SYMTTL */ 15638494Sobrien 15738494Sobrien res.ns_status = NFS_OK; 15838494Sobrien res.ns_u.ns_attr_u = slinkfattr; 15938494Sobrien } else { 16038494Sobrien if (gid != hlfs_gid) { 16138494Sobrien res.ns_status = NFSERR_STALE; 16238494Sobrien } else { 163277879Spfg (void)memcpy(&uid, argp->fh_data, sizeof(uid)); 16438494Sobrien if (plt_search(uid) != (uid2home_t *) NULL) { 16538494Sobrien res.ns_status = NFS_OK; 16638494Sobrien un_fattr.na_fileid = uid; 16738494Sobrien res.ns_u.ns_attr_u = un_fattr; 16851292Sobrien dlog("nfs_getattr: successful search for uid=%ld, gid=%ld", 16951292Sobrien (long) uid, (long) gid); 17038494Sobrien } else { /* not found */ 17138494Sobrien res.ns_status = NFSERR_STALE; 17238494Sobrien } 17338494Sobrien } 17438494Sobrien } 17538494Sobrien return &res; 17638494Sobrien} 17738494Sobrien 17838494Sobrien 17938494Sobriennfsattrstat * 18038494Sobriennfsproc_setattr_2_svc(nfssattrargs *argp, struct svc_req *rqstp) 18138494Sobrien{ 18238494Sobrien static nfsattrstat res = {NFSERR_ROFS}; 18338494Sobrien 18438494Sobrien return &res; 18538494Sobrien} 18638494Sobrien 18738494Sobrien 18838494Sobrienvoidp 18938494Sobriennfsproc_root_2_svc(voidp argp, struct svc_req *rqstp) 19038494Sobrien{ 19138494Sobrien static char res; 19238494Sobrien 19338494Sobrien return (voidp) &res; 19438494Sobrien} 19538494Sobrien 19638494Sobrien 19738494Sobriennfsdiropres * 19838494Sobriennfsproc_lookup_2_svc(nfsdiropargs *argp, struct svc_req *rqstp) 19938494Sobrien{ 20038494Sobrien static nfsdiropres res; 20138494Sobrien int idx; 20238494Sobrien uid_t uid = (uid_t) INVALIDID; 20338494Sobrien gid_t gid = (gid_t) INVALIDID; 20438494Sobrien 20538494Sobrien if (!started) { 20638494Sobrien started++; 20738494Sobrien rootfattr.na_ctime = startup; 20838494Sobrien rootfattr.na_mtime = startup; 20938494Sobrien slinkfattr.na_ctime = startup; 21038494Sobrien slinkfattr.na_mtime = startup; 21138494Sobrien un_fattr.na_ctime = startup; 21238494Sobrien un_fattr.na_mtime = startup; 21338494Sobrien } 21438494Sobrien 21538494Sobrien if (eq_fh(&argp->da_fhandle, &slink)) { 21638494Sobrien res.dr_status = NFSERR_NOTDIR; 21738494Sobrien return &res; 21838494Sobrien } 21938494Sobrien 220119679Smbr if (getcreds(rqstp, &uid, &gid, nfsxprt) < 0) { 221119679Smbr res.dr_status = NFSERR_NOENT; 222119679Smbr return &res; 223119679Smbr } 22438494Sobrien if (eq_fh(&argp->da_fhandle, &root)) { 22538494Sobrien if (argp->da_name[0] == '.' && 22638494Sobrien (argp->da_name[1] == '\0' || 22738494Sobrien (argp->da_name[1] == '.' && 22838494Sobrien argp->da_name[2] == '\0'))) { 229174294Sobrien#if 0 230174294Sobrien /* 231174294Sobrien * XXX: increment mtime of parent directory, causes NFS clients to 232174294Sobrien * invalidate their cache for that directory. 233174294Sobrien * Some NFS clients may need this code. 234174294Sobrien */ 235174294Sobrien if (uid != rootfattr.na_uid) { 236174294Sobrien clocktime(&rootfattr.na_mtime); 237174294Sobrien rootfattr.na_uid = uid; 238174294Sobrien } 239310490Scy#endif /* 0 */ 24038494Sobrien res.dr_u.dr_drok_u.drok_fhandle = root; 24138494Sobrien res.dr_u.dr_drok_u.drok_attributes = rootfattr; 24238494Sobrien res.dr_status = NFS_OK; 24338494Sobrien return &res; 24438494Sobrien } 24538494Sobrien 24638494Sobrien if (STREQ(argp->da_name, slinkname)) { 24782794Sobrien#ifndef MNT2_NFS_OPT_SYMTTL 24882794Sobrien /* 24982794Sobrien * This code is needed to defeat Solaris 2.4's (and newer) symlink 25082794Sobrien * values cache. It forces the last-modified time of the symlink to be 25182794Sobrien * current. It is not needed if the O/S has an nfs flag to turn off the 25282794Sobrien * symlink-cache at mount time (such as Irix 5.x and 6.x). -Erez. 253119679Smbr * 254119679Smbr * Additionally, Linux currently ignores the nt_useconds field, 255119679Smbr * so we must update the nt_seconds field every time. 25682794Sobrien */ 257119679Smbr if (uid != slinkfattr.na_uid) { 258174294Sobrien clocktime(&slinkfattr.na_mtime); 259119679Smbr slinkfattr.na_uid = uid; 260119679Smbr } 26182794Sobrien#endif /* not MNT2_NFS_OPT_SYMTTL */ 26238494Sobrien res.dr_u.dr_drok_u.drok_fhandle = slink; 26338494Sobrien res.dr_u.dr_drok_u.drok_attributes = slinkfattr; 26438494Sobrien res.dr_status = NFS_OK; 26538494Sobrien return &res; 26638494Sobrien } 26738494Sobrien 268119679Smbr if (gid != hlfs_gid) { 26938494Sobrien res.dr_status = NFSERR_NOENT; 27038494Sobrien return &res; 27138494Sobrien } 27238494Sobrien 27342629Sobrien /* if gets here, gid == hlfs_gid */ 27438494Sobrien if ((idx = untab_index(argp->da_name)) < 0) { 27538494Sobrien res.dr_status = NFSERR_NOENT; 27638494Sobrien return &res; 27738494Sobrien } else { /* entry found and gid is permitted */ 27838494Sobrien un_fattr.na_fileid = untab[idx].uid; 27938494Sobrien res.dr_u.dr_drok_u.drok_attributes = un_fattr; 280277879Spfg memset(&un_fhandle, 0, sizeof(un_fhandle)); 281277879Spfg memcpy(un_fhandle.fh_data, &untab[idx].uid, sizeof(untab[idx].uid)); 282174294Sobrien xstrlcpy((char *) &un_fhandle.fh_data[sizeof(int)], 283174294Sobrien untab[idx].username, 284174294Sobrien sizeof(am_nfs_fh) - sizeof(int)); 28538494Sobrien res.dr_u.dr_drok_u.drok_fhandle = un_fhandle; 28638494Sobrien res.dr_status = NFS_OK; 28751292Sobrien dlog("nfs_lookup: successful lookup for uid=%ld, gid=%ld: username=%s", 28851292Sobrien (long) uid, (long) gid, untab[idx].username); 28938494Sobrien return &res; 29038494Sobrien } 29138494Sobrien } /* end of "if (eq_fh(argp->dir.data, root.data)) {" */ 29238494Sobrien 29338494Sobrien res.dr_status = NFSERR_STALE; 29438494Sobrien return &res; 29538494Sobrien} 29638494Sobrien 29738494Sobrien 29838494Sobriennfsreadlinkres * 29938494Sobriennfsproc_readlink_2_svc(am_nfs_fh *argp, struct svc_req *rqstp) 30038494Sobrien{ 30138494Sobrien static nfsreadlinkres res; 30238494Sobrien uid_t userid = (uid_t) INVALIDID; 30338494Sobrien gid_t groupid = hlfs_gid + 1; /* anything not hlfs_gid */ 30438494Sobrien int retval = 0; 305310490Scy char *path_val = NULL; 30638494Sobrien char *username; 30738494Sobrien static uid_t last_uid = (uid_t) INVALIDID; 30838494Sobrien 30938494Sobrien if (eq_fh(argp, &root)) { 31038494Sobrien res.rlr_status = NFSERR_ISDIR; 31138494Sobrien } else if (eq_fh(argp, &slink)) { 31282794Sobrien if (getcreds(rqstp, &userid, &groupid, nfsxprt) < 0) 31338494Sobrien return (nfsreadlinkres *) NULL; 31438494Sobrien 315174294Sobrien clocktime(&slinkfattr.na_atime); 31638494Sobrien 31738494Sobrien res.rlr_status = NFS_OK; 31838494Sobrien if (groupid == hlfs_gid) { 31938494Sobrien res.rlr_u.rlr_data_u = DOTSTRING; 320119679Smbr } else if (!(res.rlr_u.rlr_data_u = path_val = homedir(userid, groupid))) { 32138494Sobrien /* 32238494Sobrien * parent process (fork in homedir()) continues 32338494Sobrien * processing, by getting a NULL returned as a 32438494Sobrien * "special". Child returns result. 32538494Sobrien */ 326310490Scy return NULL; 32738494Sobrien } 32838494Sobrien 32938494Sobrien } else { /* check if asked for user mailbox */ 33038494Sobrien 33182794Sobrien if (getcreds(rqstp, &userid, &groupid, nfsxprt) < 0) { 33238494Sobrien return (nfsreadlinkres *) NULL; 33338494Sobrien } 33438494Sobrien 33538494Sobrien if (groupid == hlfs_gid) { 336277879Spfg memcpy(&userid, argp->fh_data, sizeof(userid)); 33738494Sobrien username = (char *) &argp->fh_data[sizeof(int)]; 33838494Sobrien if (!(res.rlr_u.rlr_data_u = mailbox(userid, username))) 33938494Sobrien return (nfsreadlinkres *) NULL; 34038494Sobrien } else { 34138494Sobrien res.rlr_status = NFSERR_STALE; 34238494Sobrien } 34338494Sobrien } 34438494Sobrien 34538494Sobrien /* print info, but try to avoid repetitions */ 34638494Sobrien if (userid != last_uid) { 34751292Sobrien plog(XLOG_USER, "mailbox for uid=%ld, gid=%ld is %s", 34851292Sobrien (long) userid, (long) groupid, (char *) res.rlr_u.rlr_data_u); 34938494Sobrien last_uid = userid; 35038494Sobrien } 35138494Sobrien 352174294Sobrien /* I don't think it will pass this if -D fork */ 35338494Sobrien if (serverpid == getpid()) 35438494Sobrien return &res; 35538494Sobrien 35638494Sobrien if (!svc_sendreply(nfsxprt, (XDRPROC_T_TYPE) xdr_readlinkres, (SVC_IN_ARG_TYPE) &res)) 35738494Sobrien svcerr_systemerr(nfsxprt); 35838494Sobrien 35938494Sobrien /* 36038494Sobrien * Child exists here. We need to determine which 36138494Sobrien * exist status to return. The exit status 36238494Sobrien * is gathered using wait() and determines 36338494Sobrien * if we returned $HOME/.hlfsspool or $ALTDIR. The parent 36438494Sobrien * needs this info so it can update the lookup table. 36538494Sobrien */ 36638494Sobrien if (path_val && alt_spooldir && STREQ(path_val, alt_spooldir)) 36738494Sobrien retval = 1; /* could not get real home dir (or uid 0 user) */ 36838494Sobrien else 36938494Sobrien retval = 0; 37038494Sobrien 37138494Sobrien /* 372310490Scy * If asked for -D nofork, then must return the value, 37338494Sobrien * NOT exit, or else the main hlfsd server exits. 374310490Scy * If -D fork (default), then we do want to exit from the process. 375174294Sobrien * Bug: where is that status information being collected? 37638494Sobrien */ 377174294Sobrien if (amuDebug(D_FORK)) 378310490Scy exit(retval); 379310490Scy else 38038494Sobrien return &res; 38138494Sobrien} 38238494Sobrien 38338494Sobrien 38438494Sobriennfsreadres * 38538494Sobriennfsproc_read_2_svc(nfsreadargs *argp, struct svc_req *rqstp) 38638494Sobrien{ 38738494Sobrien static nfsreadres res = {NFSERR_ACCES}; 38838494Sobrien 38938494Sobrien return &res; 39038494Sobrien} 39138494Sobrien 39238494Sobrien 39338494Sobrienvoidp 39438494Sobriennfsproc_writecache_2_svc(voidp argp, struct svc_req *rqstp) 39538494Sobrien{ 39638494Sobrien static char res; 39738494Sobrien 39838494Sobrien return (voidp) &res; 39938494Sobrien} 40038494Sobrien 40138494Sobrien 40238494Sobriennfsattrstat * 40338494Sobriennfsproc_write_2_svc(nfswriteargs *argp, struct svc_req *rqstp) 40438494Sobrien{ 40538494Sobrien static nfsattrstat res = {NFSERR_ROFS}; 40638494Sobrien 40738494Sobrien return &res; 40838494Sobrien} 40938494Sobrien 41038494Sobrien 41138494Sobriennfsdiropres * 41238494Sobriennfsproc_create_2_svc(nfscreateargs *argp, struct svc_req *rqstp) 41338494Sobrien{ 41438494Sobrien static nfsdiropres res = {NFSERR_ROFS}; 41538494Sobrien 41638494Sobrien return &res; 41738494Sobrien} 41838494Sobrien 41938494Sobrien 42038494Sobriennfsstat * 42138494Sobriennfsproc_remove_2_svc(nfsdiropargs *argp, struct svc_req *rqstp) 42238494Sobrien{ 42338494Sobrien static nfsstat res = {NFSERR_ROFS}; 42438494Sobrien 42538494Sobrien return &res; 42638494Sobrien} 42738494Sobrien 42838494Sobrien 42938494Sobriennfsstat * 43038494Sobriennfsproc_rename_2_svc(nfsrenameargs *argp, struct svc_req *rqstp) 43138494Sobrien{ 43238494Sobrien static nfsstat res = {NFSERR_ROFS}; 43338494Sobrien 43438494Sobrien return &res; 43538494Sobrien} 43638494Sobrien 43738494Sobrien 43838494Sobriennfsstat * 43938494Sobriennfsproc_link_2_svc(nfslinkargs *argp, struct svc_req *rqstp) 44038494Sobrien{ 44138494Sobrien static nfsstat res = {NFSERR_ROFS}; 44238494Sobrien 44338494Sobrien return &res; 44438494Sobrien} 44538494Sobrien 44638494Sobrien 44738494Sobriennfsstat * 44838494Sobriennfsproc_symlink_2_svc(nfssymlinkargs *argp, struct svc_req *rqstp) 44938494Sobrien{ 45038494Sobrien static nfsstat res = {NFSERR_ROFS}; 45138494Sobrien 45238494Sobrien return &res; 45338494Sobrien} 45438494Sobrien 45538494Sobrien 45638494Sobriennfsdiropres * 45738494Sobriennfsproc_mkdir_2_svc(nfscreateargs *argp, struct svc_req *rqstp) 45838494Sobrien{ 45938494Sobrien static nfsdiropres res = {NFSERR_ROFS}; 46038494Sobrien 46138494Sobrien return &res; 46238494Sobrien} 46338494Sobrien 46438494Sobrien 46538494Sobriennfsstat * 46638494Sobriennfsproc_rmdir_2_svc(nfsdiropargs *argp, struct svc_req *rqstp) 46738494Sobrien{ 46838494Sobrien static nfsstat res = {NFSERR_ROFS}; 46938494Sobrien 47038494Sobrien return &res; 47138494Sobrien} 47238494Sobrien 47338494Sobrien 47438494Sobriennfsreaddirres * 47538494Sobriennfsproc_readdir_2_svc(nfsreaddirargs *argp, struct svc_req *rqstp) 47638494Sobrien{ 47738494Sobrien static nfsreaddirres res; 478310490Scy static nfsentry slinkent = {SLINKID, NULL, {SLINKCOOKIE}}; 47938494Sobrien static nfsentry dotdotent = {ROOTID, "..", {DOTDOTCOOKIE}, &slinkent}; 48038494Sobrien static nfsentry dotent = {ROOTID, ".", {DOTCOOKIE}, &dotdotent}; 48138494Sobrien 48238494Sobrien slinkent.ne_name = slinkname; 48338494Sobrien 48438494Sobrien if (eq_fh(&argp->rda_fhandle, &slink)) { 48538494Sobrien res.rdr_status = NFSERR_NOTDIR; 48638494Sobrien } else if (eq_fh(&argp->rda_fhandle, &root)) { 487174294Sobrien clocktime(&rootfattr.na_atime); 48838494Sobrien 48938494Sobrien res.rdr_status = NFS_OK; 49038494Sobrien switch (argp->rda_cookie[0]) { 49138494Sobrien case 0: 49238494Sobrien res.rdr_u.rdr_reply_u.dl_entries = &dotent; 49338494Sobrien break; 49438494Sobrien case DOTCOOKIE: 49538494Sobrien res.rdr_u.rdr_reply_u.dl_entries = &dotdotent; 49638494Sobrien break; 49738494Sobrien case DOTDOTCOOKIE: 49838494Sobrien res.rdr_u.rdr_reply_u.dl_entries = &slinkent; 49938494Sobrien break; 50038494Sobrien case SLINKCOOKIE: 501310490Scy res.rdr_u.rdr_reply_u.dl_entries = (nfsentry *) NULL; 50238494Sobrien break; 50338494Sobrien } 50438494Sobrien res.rdr_u.rdr_reply_u.dl_eof = TRUE; 50538494Sobrien } else { 50638494Sobrien res.rdr_status = NFSERR_STALE; 50738494Sobrien } 50838494Sobrien return &res; 50938494Sobrien} 51038494Sobrien 51138494Sobrien 51238494Sobriennfsstatfsres * 51338494Sobriennfsproc_statfs_2_svc(am_nfs_fh *argp, struct svc_req *rqstp) 51438494Sobrien{ 51538494Sobrien static nfsstatfsres res = {NFS_OK}; 51638494Sobrien 51738494Sobrien res.sfr_u.sfr_reply_u.sfrok_tsize = 1024; 51838494Sobrien res.sfr_u.sfr_reply_u.sfrok_bsize = 1024; 51938494Sobrien 52038494Sobrien /* 52138494Sobrien * Some "df" programs automatically assume that file systems 52238494Sobrien * with zero blocks are meta-filesystems served by automounters. 52338494Sobrien */ 52438494Sobrien res.sfr_u.sfr_reply_u.sfrok_blocks = 0; 52538494Sobrien res.sfr_u.sfr_reply_u.sfrok_bfree = 0; 52638494Sobrien res.sfr_u.sfr_reply_u.sfrok_bavail = 0; 52738494Sobrien 52838494Sobrien return &res; 52938494Sobrien} 530