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/nfs_prot_svc.c
4138494Sobrien *
4238494Sobrien */
4338494Sobrien
4438494Sobrien#ifdef HAVE_CONFIG_H
4538494Sobrien# include <config.h>
4638494Sobrien#endif /* HAVE_CONFIG_H */
4738494Sobrien#include <am_defs.h>
4838494Sobrien#include <hlfsd.h>
4938494Sobrien
5038494Sobrien/* EXTERNAL FUNCTIONS */
5138494Sobrienextern voidp nfsproc_null_2_svc(voidp, struct svc_req *);
5282794Sobrienextern nfsattrstat *nfsproc_getattr_2_svc(am_nfs_fh *, struct svc_req *);
5382794Sobrienextern nfsattrstat *nfsproc_setattr_2_svc(nfssattrargs *, struct svc_req *);
5438494Sobrienextern voidp nfsproc_root_2_svc(voidp, struct svc_req *);
5582794Sobrienextern nfsdiropres *nfsproc_lookup_2_svc(nfsdiropargs *, struct svc_req *);
5682794Sobrienextern nfsreadlinkres *nfsproc_readlink_2_svc(am_nfs_fh *, struct svc_req *);
5782794Sobrienextern nfsreadres *nfsproc_read_2_svc(nfsreadargs *, struct svc_req *);
5838494Sobrienextern voidp nfsproc_writecache_2_svc(voidp, struct svc_req *);
5982794Sobrienextern nfsattrstat *nfsproc_write_2_svc(nfswriteargs *, struct svc_req *);
6082794Sobrienextern nfsdiropres *nfsproc_create_2_svc(nfscreateargs *, struct svc_req *);
6182794Sobrienextern nfsstat *nfsproc_remove_2_svc(nfsdiropargs *, struct svc_req *);
6282794Sobrienextern nfsstat *nfsproc_rename_2_svc(nfsrenameargs *, struct svc_req *);
6382794Sobrienextern nfsstat *nfsproc_link_2_svc(nfslinkargs *, struct svc_req *);
6482794Sobrienextern nfsstat *nfsproc_symlink_2_svc(nfssymlinkargs *, struct svc_req *);
6582794Sobrienextern nfsdiropres *nfsproc_mkdir_2_svc(nfscreateargs *, struct svc_req *);
6682794Sobrienextern nfsstat *nfsproc_rmdir_2_svc(nfsdiropargs *, struct svc_req *);
6782794Sobrienextern nfsreaddirres *nfsproc_readdir_2_svc(nfsreaddirargs *, struct svc_req *);
6882794Sobrienextern nfsstatfsres *nfsproc_statfs_2_svc(am_nfs_fh *, struct svc_req *);
6938494Sobrien
7038494Sobrien/* GLOBALS */
7138494SobrienSVCXPRT *nfs_program_2_transp;
7238494Sobrien
7338494Sobrien/* TYPEDEFS */
7438494Sobrientypedef char *(*nfssvcproc_t)(voidp, struct svc_req *);
7538494Sobrien
7638494Sobrien
7738494Sobrienvoid
7838494Sobriennfs_program_2(struct svc_req *rqstp, SVCXPRT *transp)
7938494Sobrien{
8038494Sobrien  union {
8138494Sobrien    am_nfs_fh		nfsproc_getattr_2_arg;
8238494Sobrien    nfssattrargs	nfsproc_setattr_2_arg;
8338494Sobrien    nfsdiropargs	nfsproc_lookup_2_arg;
8438494Sobrien    am_nfs_fh		nfsproc_readlink_2_arg;
8538494Sobrien    nfsreadargs		nfsproc_read_2_arg;
8638494Sobrien    nfswriteargs	nfsproc_write_2_arg;
8738494Sobrien    nfscreateargs	nfsproc_create_2_arg;
8838494Sobrien    nfsdiropargs	nfsproc_remove_2_arg;
8938494Sobrien    nfsrenameargs	nfsproc_rename_2_arg;
9038494Sobrien    nfslinkargs		nfsproc_link_2_arg;
9138494Sobrien    nfssymlinkargs	nfsproc_symlink_2_arg;
9238494Sobrien    nfscreateargs	nfsproc_mkdir_2_arg;
9338494Sobrien    nfsdiropargs	nfsproc_rmdir_2_arg;
9438494Sobrien    nfsreaddirargs	nfsproc_readdir_2_arg;
9538494Sobrien    am_nfs_fh		nfsproc_statfs_2_arg;
9638494Sobrien  } argument;
9738494Sobrien  char *result;
9838494Sobrien  xdrproc_t xdr_argument, xdr_result;
9938494Sobrien  nfssvcproc_t local;
10038494Sobrien
10138494Sobrien  nfs_program_2_transp = NULL;
10238494Sobrien
10338494Sobrien  switch (rqstp->rq_proc) {
10438494Sobrien
10538494Sobrien  case NFSPROC_NULL:
10638494Sobrien    xdr_argument = (xdrproc_t) xdr_void;
10738494Sobrien    xdr_result = (xdrproc_t) xdr_void;
10838494Sobrien    local = (nfssvcproc_t) nfsproc_null_2_svc;
10938494Sobrien    break;
11038494Sobrien
11138494Sobrien  case NFSPROC_GETATTR:
11238494Sobrien    xdr_argument = (xdrproc_t) xdr_nfs_fh;
11338494Sobrien    xdr_result = (xdrproc_t) xdr_attrstat;
11438494Sobrien    local = (nfssvcproc_t) nfsproc_getattr_2_svc;
11538494Sobrien    break;
11638494Sobrien
11738494Sobrien  case NFSPROC_SETATTR:
11838494Sobrien    xdr_argument = (xdrproc_t) xdr_sattrargs;
11938494Sobrien    xdr_result = (xdrproc_t) xdr_attrstat;
12038494Sobrien    local = (nfssvcproc_t) nfsproc_setattr_2_svc;
12138494Sobrien    break;
12238494Sobrien
12338494Sobrien  case NFSPROC_ROOT:
12438494Sobrien    xdr_argument = (xdrproc_t) xdr_void;
12538494Sobrien    xdr_result = (xdrproc_t) xdr_void;
12638494Sobrien    local = (nfssvcproc_t) nfsproc_root_2_svc;
12738494Sobrien    break;
12838494Sobrien
12938494Sobrien  case NFSPROC_LOOKUP:
13038494Sobrien    xdr_argument = (xdrproc_t) xdr_diropargs;
13138494Sobrien    xdr_result = (xdrproc_t) xdr_diropres;
13238494Sobrien    local = (nfssvcproc_t) nfsproc_lookup_2_svc;
13338494Sobrien    /*
13438494Sobrien     * Cheap way to pass transp down to afs_lookuppn so it can
13538494Sobrien     * be stored in the am_node structure and later used for
13638494Sobrien     * quick_reply().
13738494Sobrien     */
13838494Sobrien    nfs_program_2_transp = transp;
13938494Sobrien    break;
14038494Sobrien
14138494Sobrien  case NFSPROC_READLINK:
14238494Sobrien    xdr_argument = (xdrproc_t) xdr_nfs_fh;
14338494Sobrien    xdr_result = (xdrproc_t) xdr_readlinkres;
14438494Sobrien    local = (nfssvcproc_t) nfsproc_readlink_2_svc;
14538494Sobrien    break;
14638494Sobrien
14738494Sobrien  case NFSPROC_READ:
14838494Sobrien    xdr_argument = (xdrproc_t) xdr_readargs;
14938494Sobrien    xdr_result = (xdrproc_t) xdr_readres;
15038494Sobrien    local = (nfssvcproc_t) nfsproc_read_2_svc;
15138494Sobrien    break;
15238494Sobrien
15338494Sobrien  case NFSPROC_WRITECACHE:
15438494Sobrien    xdr_argument = (xdrproc_t) xdr_void;
15538494Sobrien    xdr_result = (xdrproc_t) xdr_void;
15638494Sobrien    local = (nfssvcproc_t) nfsproc_writecache_2_svc;
15738494Sobrien    break;
15838494Sobrien
15938494Sobrien  case NFSPROC_WRITE:
16038494Sobrien    xdr_argument = (xdrproc_t) xdr_writeargs;
16138494Sobrien    xdr_result = (xdrproc_t) xdr_attrstat;
16238494Sobrien    local = (nfssvcproc_t) nfsproc_write_2_svc;
16338494Sobrien    break;
16438494Sobrien
16538494Sobrien  case NFSPROC_CREATE:
16638494Sobrien    xdr_argument = (xdrproc_t) xdr_createargs;
16738494Sobrien    xdr_result = (xdrproc_t) xdr_diropres;
16838494Sobrien    local = (nfssvcproc_t) nfsproc_create_2_svc;
16938494Sobrien    break;
17038494Sobrien
17138494Sobrien  case NFSPROC_REMOVE:
17238494Sobrien    xdr_argument = (xdrproc_t) xdr_diropargs;
17338494Sobrien    xdr_result = (xdrproc_t) xdr_nfsstat;
17438494Sobrien    local = (nfssvcproc_t) nfsproc_remove_2_svc;
17538494Sobrien    break;
17638494Sobrien
17738494Sobrien  case NFSPROC_RENAME:
17838494Sobrien    xdr_argument = (xdrproc_t) xdr_renameargs;
17938494Sobrien    xdr_result = (xdrproc_t) xdr_nfsstat;
18038494Sobrien    local = (nfssvcproc_t) nfsproc_rename_2_svc;
18138494Sobrien    break;
18238494Sobrien
18338494Sobrien  case NFSPROC_LINK:
18438494Sobrien    xdr_argument = (xdrproc_t) xdr_linkargs;
18538494Sobrien    xdr_result = (xdrproc_t) xdr_nfsstat;
18638494Sobrien    local = (nfssvcproc_t) nfsproc_link_2_svc;
18738494Sobrien    break;
18838494Sobrien
18938494Sobrien  case NFSPROC_SYMLINK:
19038494Sobrien    xdr_argument = (xdrproc_t) xdr_symlinkargs;
19138494Sobrien    xdr_result = (xdrproc_t) xdr_nfsstat;
19238494Sobrien    local = (nfssvcproc_t) nfsproc_symlink_2_svc;
19338494Sobrien    break;
19438494Sobrien
19538494Sobrien  case NFSPROC_MKDIR:
19638494Sobrien    xdr_argument = (xdrproc_t) xdr_createargs;
19738494Sobrien    xdr_result = (xdrproc_t) xdr_diropres;
19838494Sobrien    local = (nfssvcproc_t) nfsproc_mkdir_2_svc;
19938494Sobrien    break;
20038494Sobrien
20138494Sobrien  case NFSPROC_RMDIR:
20238494Sobrien    xdr_argument = (xdrproc_t) xdr_diropargs;
20338494Sobrien    xdr_result = (xdrproc_t) xdr_nfsstat;
20438494Sobrien    local = (nfssvcproc_t) nfsproc_rmdir_2_svc;
20538494Sobrien    break;
20638494Sobrien
20738494Sobrien  case NFSPROC_READDIR:
20838494Sobrien    xdr_argument = (xdrproc_t) xdr_readdirargs;
20938494Sobrien    xdr_result = (xdrproc_t) xdr_readdirres;
21038494Sobrien    local = (nfssvcproc_t) nfsproc_readdir_2_svc;
21138494Sobrien    break;
21238494Sobrien
21338494Sobrien  case NFSPROC_STATFS:
21438494Sobrien    xdr_argument = (xdrproc_t) xdr_nfs_fh;
21538494Sobrien    xdr_result = (xdrproc_t) xdr_statfsres;
21638494Sobrien    local = (nfssvcproc_t) nfsproc_statfs_2_svc;
21738494Sobrien    break;
21838494Sobrien
21938494Sobrien  default:
22038494Sobrien    svcerr_noproc(transp);
22138494Sobrien    return;
22238494Sobrien  }
22338494Sobrien
22438494Sobrien  memset((char *) &argument, 0, sizeof(argument));
22538494Sobrien  if (!svc_getargs(transp,
22638494Sobrien		   (XDRPROC_T_TYPE) xdr_argument,
22738494Sobrien		   (SVC_IN_ARG_TYPE) &argument)) {
22838494Sobrien    plog(XLOG_ERROR,
22938494Sobrien	 "NFS xdr decode failed for %d %d %d",
23051292Sobrien	 (int) rqstp->rq_prog, (int) rqstp->rq_vers, (int) rqstp->rq_proc);
23138494Sobrien    svcerr_decode(transp);
23238494Sobrien    return;
23338494Sobrien  }
23438494Sobrien  result = (*local) (&argument, rqstp);
23538494Sobrien
23638494Sobrien  nfs_program_2_transp = NULL;
23738494Sobrien
23838494Sobrien  if (result != NULL && !svc_sendreply(transp,
23938494Sobrien				       (XDRPROC_T_TYPE) xdr_result,
24038494Sobrien				       result)) {
24138494Sobrien    svcerr_systemerr(transp);
24238494Sobrien  }
24338494Sobrien  if (!svc_freeargs(transp,
24438494Sobrien		    (XDRPROC_T_TYPE) xdr_argument,
24538494Sobrien		    (SVC_IN_ARG_TYPE) & argument)) {
24638494Sobrien    plog(XLOG_FATAL, "unable to free rpc arguments in nfs_program_2");
24738494Sobrien    going_down(1);
24838494Sobrien  }
24938494Sobrien}
250