xref: /onnv-gate/usr/src/uts/common/fs/autofs/auto_xdr.c (revision 2170:eb691d2a219e)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*2170Sevanl  * Common Development and Distribution License (the "License").
6*2170Sevanl  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*2170Sevanl  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate /*
290Sstevel@tonic-gate  * This file can not be automatically generated by rpcgen from
300Sstevel@tonic-gate  * autofs_prot.x because of the xdr routines that provide readdir
310Sstevel@tonic-gate  * support, its own implementation of xdr_autofs_netbuf(). rpcgen will
320Sstevel@tonic-gate  * also generate xdr routines with recursion which should not be used
330Sstevel@tonic-gate  * in the kernel.
340Sstevel@tonic-gate  */
350Sstevel@tonic-gate 
360Sstevel@tonic-gate #include <sys/param.h>
370Sstevel@tonic-gate #include <sys/kmem.h>
380Sstevel@tonic-gate #include <sys/errno.h>
390Sstevel@tonic-gate #include <sys/proc.h>
400Sstevel@tonic-gate #include <sys/vfs.h>
410Sstevel@tonic-gate #include <sys/vnode.h>
420Sstevel@tonic-gate #include <sys/pathname.h>
430Sstevel@tonic-gate #include <sys/cred.h>
440Sstevel@tonic-gate #include <sys/mount.h>
450Sstevel@tonic-gate #include <sys/cmn_err.h>
460Sstevel@tonic-gate #include <sys/debug.h>
470Sstevel@tonic-gate #include <sys/systm.h>
480Sstevel@tonic-gate #include <rpc/types.h>
490Sstevel@tonic-gate #include <rpc/xdr.h>
500Sstevel@tonic-gate #include <rpc/auth.h>
510Sstevel@tonic-gate #include <rpc/clnt.h>
520Sstevel@tonic-gate #include <sys/ticotsord.h>
530Sstevel@tonic-gate #include <sys/dirent.h>
54*2170Sevanl #include <sys/sysmacros.h>
550Sstevel@tonic-gate #include <fs/fs_subr.h>
560Sstevel@tonic-gate #include <sys/fs/autofs.h>
570Sstevel@tonic-gate 
580Sstevel@tonic-gate bool_t xdr_autofs_netbuf(XDR *, struct netbuf *);
590Sstevel@tonic-gate bool_t xdr_mounta(XDR *, struct mounta *);
600Sstevel@tonic-gate 
610Sstevel@tonic-gate bool_t
620Sstevel@tonic-gate xdr_umntrequest(XDR *xdrs, umntrequest *objp)
630Sstevel@tonic-gate {
640Sstevel@tonic-gate 	bool_t more_data;
650Sstevel@tonic-gate 
660Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_ENCODE);
670Sstevel@tonic-gate 
680Sstevel@tonic-gate 	for (; objp != NULL; objp = objp->next) {
690Sstevel@tonic-gate 		if (!xdr_bool_t(xdrs, &objp->isdirect))
700Sstevel@tonic-gate 			return (FALSE);
710Sstevel@tonic-gate 		if (!xdr_string(xdrs, &objp->mntresource, AUTOFS_MAXPATHLEN))
720Sstevel@tonic-gate 			return (FALSE);
730Sstevel@tonic-gate 		if (!xdr_string(xdrs, &objp->mntpnt, AUTOFS_MAXPATHLEN))
740Sstevel@tonic-gate 			return (FALSE);
750Sstevel@tonic-gate 		if (!xdr_string(xdrs, &objp->fstype, AUTOFS_MAXCOMPONENTLEN))
760Sstevel@tonic-gate 			return (FALSE);
770Sstevel@tonic-gate 		if (!xdr_string(xdrs, &objp->mntopts, AUTOFS_MAXOPTSLEN))
780Sstevel@tonic-gate 			return (FALSE);
790Sstevel@tonic-gate 
800Sstevel@tonic-gate 		if (objp->next != NULL)
810Sstevel@tonic-gate 			more_data = TRUE;
820Sstevel@tonic-gate 		else
830Sstevel@tonic-gate 			more_data = FALSE;
840Sstevel@tonic-gate 
850Sstevel@tonic-gate 		if (!xdr_bool(xdrs, &more_data))
860Sstevel@tonic-gate 			return (FALSE);
870Sstevel@tonic-gate 	}
880Sstevel@tonic-gate 	return (TRUE);
890Sstevel@tonic-gate }
900Sstevel@tonic-gate 
910Sstevel@tonic-gate bool_t
920Sstevel@tonic-gate xdr_umntres(XDR *xdrs, umntres *objp)
930Sstevel@tonic-gate {
940Sstevel@tonic-gate 	return (xdr_int(xdrs, &objp->status));
950Sstevel@tonic-gate }
960Sstevel@tonic-gate 
970Sstevel@tonic-gate bool_t
980Sstevel@tonic-gate xdr_autofs_stat(XDR *xdrs, autofs_stat *objp)
990Sstevel@tonic-gate {
1000Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)objp))
1010Sstevel@tonic-gate 		return (FALSE);
1020Sstevel@tonic-gate 	return (TRUE);
1030Sstevel@tonic-gate }
1040Sstevel@tonic-gate 
1050Sstevel@tonic-gate bool_t
1060Sstevel@tonic-gate xdr_autofs_action(XDR *xdrs, autofs_action *objp)
1070Sstevel@tonic-gate {
1080Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)objp))
1090Sstevel@tonic-gate 		return (FALSE);
1100Sstevel@tonic-gate 	return (TRUE);
1110Sstevel@tonic-gate }
1120Sstevel@tonic-gate 
1130Sstevel@tonic-gate bool_t
1140Sstevel@tonic-gate xdr_linka(XDR *xdrs, linka *objp)
1150Sstevel@tonic-gate {
1160Sstevel@tonic-gate 	if (!xdr_string(xdrs, &objp->dir, AUTOFS_MAXPATHLEN))
1170Sstevel@tonic-gate 		return (FALSE);
1180Sstevel@tonic-gate 	if (!xdr_string(xdrs, &objp->link, AUTOFS_MAXPATHLEN))
1190Sstevel@tonic-gate 		return (FALSE);
1200Sstevel@tonic-gate 	return (TRUE);
1210Sstevel@tonic-gate }
1220Sstevel@tonic-gate 
1230Sstevel@tonic-gate bool_t
1240Sstevel@tonic-gate xdr_autofs_args(XDR *xdrs, autofs_args *objp)
1250Sstevel@tonic-gate {
1260Sstevel@tonic-gate 	if (!xdr_autofs_netbuf(xdrs, &objp->addr))
1270Sstevel@tonic-gate 		return (FALSE);
1280Sstevel@tonic-gate 	if (!xdr_string(xdrs, &objp->path, AUTOFS_MAXPATHLEN))
1290Sstevel@tonic-gate 		return (FALSE);
1300Sstevel@tonic-gate 	if (!xdr_string(xdrs, &objp->opts, AUTOFS_MAXOPTSLEN))
1310Sstevel@tonic-gate 		return (FALSE);
1320Sstevel@tonic-gate 	if (!xdr_string(xdrs, &objp->map, AUTOFS_MAXPATHLEN))
1330Sstevel@tonic-gate 		return (FALSE);
1340Sstevel@tonic-gate 	if (!xdr_string(xdrs, &objp->subdir, AUTOFS_MAXPATHLEN))
1350Sstevel@tonic-gate 		return (FALSE);
1360Sstevel@tonic-gate 	if (!xdr_string(xdrs, &objp->key, AUTOFS_MAXCOMPONENTLEN))
1370Sstevel@tonic-gate 		return (FALSE);
1380Sstevel@tonic-gate 	if (!xdr_int(xdrs, &objp->mount_to))
1390Sstevel@tonic-gate 		return (FALSE);
1400Sstevel@tonic-gate 	if (!xdr_int(xdrs, &objp->rpc_to))
1410Sstevel@tonic-gate 		return (FALSE);
1420Sstevel@tonic-gate 	if (!xdr_int(xdrs, &objp->direct))
1430Sstevel@tonic-gate 		return (FALSE);
1440Sstevel@tonic-gate 	return (TRUE);
1450Sstevel@tonic-gate }
1460Sstevel@tonic-gate 
1470Sstevel@tonic-gate bool_t
1480Sstevel@tonic-gate xdr_action_list_entry(XDR *xdrs, action_list_entry *objp)
1490Sstevel@tonic-gate {
1500Sstevel@tonic-gate 	if (!xdr_autofs_action(xdrs, &objp->action))
1510Sstevel@tonic-gate 		return (FALSE);
1520Sstevel@tonic-gate 	switch (objp->action) {
1530Sstevel@tonic-gate 	case AUTOFS_MOUNT_RQ:
1540Sstevel@tonic-gate 		if (!xdr_mounta(xdrs, &objp->action_list_entry_u.mounta))
1550Sstevel@tonic-gate 			return (FALSE);
1560Sstevel@tonic-gate 		break;
1570Sstevel@tonic-gate 	case AUTOFS_LINK_RQ:
1580Sstevel@tonic-gate 		if (!xdr_linka(xdrs, &objp->action_list_entry_u.linka))
1590Sstevel@tonic-gate 			return (FALSE);
1600Sstevel@tonic-gate 		break;
1610Sstevel@tonic-gate 	default:
1620Sstevel@tonic-gate 		break;
1630Sstevel@tonic-gate 	}
1640Sstevel@tonic-gate 	return (TRUE);
1650Sstevel@tonic-gate }
1660Sstevel@tonic-gate 
1670Sstevel@tonic-gate bool_t
1680Sstevel@tonic-gate xdr_action_list(XDR *xdrs, action_list *objp)
1690Sstevel@tonic-gate {
1700Sstevel@tonic-gate 	bool_t more_data = TRUE;
1710Sstevel@tonic-gate 	bool_t status = TRUE;
1720Sstevel@tonic-gate 	action_list *p;
1730Sstevel@tonic-gate 
1740Sstevel@tonic-gate 	ASSERT((xdrs->x_op == XDR_DECODE) || (xdrs->x_op == XDR_FREE));
1750Sstevel@tonic-gate 
1760Sstevel@tonic-gate 	more_data = (objp != NULL);
1770Sstevel@tonic-gate 	p = objp;
1780Sstevel@tonic-gate 
1790Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
1800Sstevel@tonic-gate 		goto free;
1810Sstevel@tonic-gate 
1820Sstevel@tonic-gate 	while (more_data) {
1830Sstevel@tonic-gate 		if (!xdr_action_list_entry(xdrs, &p->action))
1840Sstevel@tonic-gate 			goto free;
1850Sstevel@tonic-gate 
1860Sstevel@tonic-gate 		if (!xdr_bool(xdrs, &more_data))
1870Sstevel@tonic-gate 			goto free;
1880Sstevel@tonic-gate 
1890Sstevel@tonic-gate 		if (more_data) {
1900Sstevel@tonic-gate 			p->next = kmem_zalloc(sizeof (action_list), KM_SLEEP);
1910Sstevel@tonic-gate 			p = p->next;
1920Sstevel@tonic-gate 			if (p == NULL) {
1930Sstevel@tonic-gate 				status = FALSE;
1940Sstevel@tonic-gate 				goto free;
1950Sstevel@tonic-gate 			}
1960Sstevel@tonic-gate 		} else
1970Sstevel@tonic-gate 			p->next = NULL;
1980Sstevel@tonic-gate 	}
1990Sstevel@tonic-gate 	return (TRUE);
2000Sstevel@tonic-gate 
2010Sstevel@tonic-gate free:
2020Sstevel@tonic-gate 	for (p = objp; p != NULL; ) {
2030Sstevel@tonic-gate 		if (!xdr_action_list_entry(xdrs, &objp->action))
2040Sstevel@tonic-gate 			cmn_err(CE_WARN, "xdr_action_list: "
2050Sstevel@tonic-gate 			    "action_list_entry free failed %p\n",
2060Sstevel@tonic-gate 			    (void *)&objp->action);
2070Sstevel@tonic-gate 		p = p->next;
2080Sstevel@tonic-gate 		kmem_free(objp, sizeof (*objp));
2090Sstevel@tonic-gate 		objp = p;
2100Sstevel@tonic-gate 	}
2110Sstevel@tonic-gate 	objp = NULL;
2120Sstevel@tonic-gate 
2130Sstevel@tonic-gate 	return (status);
2140Sstevel@tonic-gate }
2150Sstevel@tonic-gate 
2160Sstevel@tonic-gate bool_t
2170Sstevel@tonic-gate xdr_autofs_netbuf(XDR *xdrs, struct netbuf *objp)
2180Sstevel@tonic-gate {
2190Sstevel@tonic-gate 	bool_t dummy;
2200Sstevel@tonic-gate 
2210Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, (uint_t *)&objp->maxlen))
2220Sstevel@tonic-gate 		return (FALSE);
2230Sstevel@tonic-gate 	dummy = xdr_bytes(xdrs, (char **)&(objp->buf),
2240Sstevel@tonic-gate 	    (uint_t *)&(objp->len), objp->maxlen);
2250Sstevel@tonic-gate 	return (dummy);
2260Sstevel@tonic-gate }
2270Sstevel@tonic-gate 
2280Sstevel@tonic-gate bool_t
2290Sstevel@tonic-gate xdr_mounta(XDR *xdrs, struct mounta *objp)
2300Sstevel@tonic-gate {
2310Sstevel@tonic-gate 	if (!xdr_string(xdrs, &objp->spec, AUTOFS_MAXPATHLEN))
2320Sstevel@tonic-gate 		return (FALSE);
2330Sstevel@tonic-gate 	if (!xdr_string(xdrs, &objp->dir, AUTOFS_MAXPATHLEN))
2340Sstevel@tonic-gate 		return (FALSE);
2350Sstevel@tonic-gate 	if (!xdr_int(xdrs, &objp->flags))
2360Sstevel@tonic-gate 		return (FALSE);
2370Sstevel@tonic-gate 	if (!xdr_string(xdrs, &objp->fstype, AUTOFS_MAXCOMPONENTLEN))
2380Sstevel@tonic-gate 		return (FALSE);
2390Sstevel@tonic-gate 	if (!xdr_pointer(xdrs, (char **)&objp->dataptr, sizeof (autofs_args),
2400Sstevel@tonic-gate 	    (xdrproc_t)xdr_autofs_args))
2410Sstevel@tonic-gate 		return (FALSE);
2420Sstevel@tonic-gate 	/*
2430Sstevel@tonic-gate 	 * The length is the original user-land length, not the
2440Sstevel@tonic-gate 	 * length of the native kernel autofs_args structure provided
2450Sstevel@tonic-gate 	 * after we decode the xdr buffer.  So passing the user's idea of
2460Sstevel@tonic-gate 	 * the length is wrong and we need to stuff the length field with
2470Sstevel@tonic-gate 	 * the length of the native structure.
2480Sstevel@tonic-gate 	 */
2490Sstevel@tonic-gate 	if (!xdr_int(xdrs, &objp->datalen))
2500Sstevel@tonic-gate 		return (FALSE);
2510Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE)
2520Sstevel@tonic-gate 		objp->datalen = sizeof (struct autofs_args);
2530Sstevel@tonic-gate 	if (!xdr_string(xdrs, &objp->optptr, AUTOFS_MAXOPTSLEN))
2540Sstevel@tonic-gate 		return (FALSE);
2550Sstevel@tonic-gate 	if (!xdr_int(xdrs, &objp->optlen))
2560Sstevel@tonic-gate 		return (FALSE);
2570Sstevel@tonic-gate 	ASSERT((xdrs->x_op == XDR_DECODE) || (xdrs->x_op == XDR_FREE));
2580Sstevel@tonic-gate 	return (TRUE);
2590Sstevel@tonic-gate }
2600Sstevel@tonic-gate 
2610Sstevel@tonic-gate bool_t
2620Sstevel@tonic-gate xdr_autofs_res(XDR *xdrs, autofs_res *objp)
2630Sstevel@tonic-gate {
2640Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)objp))
2650Sstevel@tonic-gate 		return (FALSE);
2660Sstevel@tonic-gate 	return (TRUE);
2670Sstevel@tonic-gate }
2680Sstevel@tonic-gate 
2690Sstevel@tonic-gate bool_t
2700Sstevel@tonic-gate xdr_autofs_lookupargs(XDR *xdrs, autofs_lookupargs *objp)
2710Sstevel@tonic-gate {
2720Sstevel@tonic-gate 	if (!xdr_string(xdrs, &objp->map, AUTOFS_MAXPATHLEN))
2730Sstevel@tonic-gate 		return (FALSE);
2740Sstevel@tonic-gate 	if (!xdr_string(xdrs, &objp->path, AUTOFS_MAXPATHLEN))
2750Sstevel@tonic-gate 		return (FALSE);
2760Sstevel@tonic-gate 	if (!xdr_string(xdrs, &objp->name, AUTOFS_MAXCOMPONENTLEN))
2770Sstevel@tonic-gate 		return (FALSE);
2780Sstevel@tonic-gate 	if (!xdr_string(xdrs, &objp->subdir, AUTOFS_MAXPATHLEN))
2790Sstevel@tonic-gate 		return (FALSE);
2800Sstevel@tonic-gate 	if (!xdr_string(xdrs, &objp->opts, AUTOFS_MAXOPTSLEN))
2810Sstevel@tonic-gate 		return (FALSE);
2820Sstevel@tonic-gate 	if (!xdr_bool_t(xdrs, &objp->isdirect))
2830Sstevel@tonic-gate 		return (FALSE);
2840Sstevel@tonic-gate 	return (TRUE);
2850Sstevel@tonic-gate }
2860Sstevel@tonic-gate 
2870Sstevel@tonic-gate bool_t
2880Sstevel@tonic-gate xdr_mount_result_type(XDR *xdrs, mount_result_type *objp)
2890Sstevel@tonic-gate {
2900Sstevel@tonic-gate 	if (!xdr_autofs_stat(xdrs, &objp->status))
2910Sstevel@tonic-gate 		return (FALSE);
2920Sstevel@tonic-gate 	switch (objp->status) {
2930Sstevel@tonic-gate 	case AUTOFS_ACTION:
2940Sstevel@tonic-gate 		if (!xdr_pointer(xdrs,
2950Sstevel@tonic-gate 		    (char **)&objp->mount_result_type_u.list,
2960Sstevel@tonic-gate 		    sizeof (action_list), (xdrproc_t)xdr_action_list))
2970Sstevel@tonic-gate 			return (FALSE);
2980Sstevel@tonic-gate 		break;
2990Sstevel@tonic-gate 	case AUTOFS_DONE:
3000Sstevel@tonic-gate 		if (!xdr_int(xdrs, &objp->mount_result_type_u.error))
3010Sstevel@tonic-gate 			return (FALSE);
3020Sstevel@tonic-gate 		break;
3030Sstevel@tonic-gate 	}
3040Sstevel@tonic-gate 	return (TRUE);
3050Sstevel@tonic-gate }
3060Sstevel@tonic-gate 
3070Sstevel@tonic-gate bool_t
3080Sstevel@tonic-gate xdr_autofs_mountres(XDR *xdrs, autofs_mountres *objp)
3090Sstevel@tonic-gate {
3100Sstevel@tonic-gate 	if (!xdr_mount_result_type(xdrs, &objp->mr_type))
3110Sstevel@tonic-gate 		return (FALSE);
3120Sstevel@tonic-gate 	if (!xdr_int(xdrs, &objp->mr_verbose))
3130Sstevel@tonic-gate 		return (FALSE);
3140Sstevel@tonic-gate 	return (TRUE);
3150Sstevel@tonic-gate }
3160Sstevel@tonic-gate 
3170Sstevel@tonic-gate bool_t
3180Sstevel@tonic-gate xdr_lookup_result_type(XDR *xdrs, lookup_result_type *objp)
3190Sstevel@tonic-gate {
3200Sstevel@tonic-gate 	if (!xdr_autofs_action(xdrs, &objp->action))
3210Sstevel@tonic-gate 		return (FALSE);
3220Sstevel@tonic-gate 	switch (objp->action) {
3230Sstevel@tonic-gate 	case AUTOFS_LINK_RQ:
3240Sstevel@tonic-gate 		if (!xdr_linka(xdrs, &objp->lookup_result_type_u.lt_linka))
3250Sstevel@tonic-gate 			return (FALSE);
3260Sstevel@tonic-gate 		break;
3270Sstevel@tonic-gate 	default:
3280Sstevel@tonic-gate 		break;
3290Sstevel@tonic-gate 	}
3300Sstevel@tonic-gate 	return (TRUE);
3310Sstevel@tonic-gate }
3320Sstevel@tonic-gate 
3330Sstevel@tonic-gate bool_t
3340Sstevel@tonic-gate xdr_autofs_lookupres(XDR *xdrs, autofs_lookupres *objp)
3350Sstevel@tonic-gate {
3360Sstevel@tonic-gate 	if (!xdr_autofs_res(xdrs, &objp->lu_res))
3370Sstevel@tonic-gate 		return (FALSE);
3380Sstevel@tonic-gate 	if (!xdr_lookup_result_type(xdrs, &objp->lu_type))
3390Sstevel@tonic-gate 		return (FALSE);
3400Sstevel@tonic-gate 	if (!xdr_int(xdrs, &objp->lu_verbose))
3410Sstevel@tonic-gate 		return (FALSE);
3420Sstevel@tonic-gate 	return (TRUE);
3430Sstevel@tonic-gate }
3440Sstevel@tonic-gate 
3450Sstevel@tonic-gate bool_t
3460Sstevel@tonic-gate xdr_autofs_rddirargs(XDR *xdrs, autofs_rddirargs *objp)
3470Sstevel@tonic-gate {
3480Sstevel@tonic-gate 	if (!xdr_string(xdrs, &objp->rda_map, AUTOFS_MAXPATHLEN))
3490Sstevel@tonic-gate 		return (FALSE);
3500Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->rda_offset))
3510Sstevel@tonic-gate 		return (FALSE);
3520Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->rda_count))
3530Sstevel@tonic-gate 		return (FALSE);
3540Sstevel@tonic-gate 	return (TRUE);
3550Sstevel@tonic-gate }
3560Sstevel@tonic-gate 
3570Sstevel@tonic-gate /*
3580Sstevel@tonic-gate  * Directory read reply:
3590Sstevel@tonic-gate  * union (enum autofs_res) {
3600Sstevel@tonic-gate  *	AUTOFS_OK: entlist;
3610Sstevel@tonic-gate  *		 boolean eof;
3620Sstevel@tonic-gate  *	default:
3630Sstevel@tonic-gate  * }
3640Sstevel@tonic-gate  *
3650Sstevel@tonic-gate  * Directory entries
3660Sstevel@tonic-gate  *	struct  direct {
3670Sstevel@tonic-gate  *		off_t   d_off;			* offset of next entry *
3680Sstevel@tonic-gate  *		u_long  d_fileno;		* inode number of entry *
3690Sstevel@tonic-gate  *		ushort_t d_reclen;		* length of this record *
3700Sstevel@tonic-gate  *		ushort_t d_namlen;		* length of string in d_name *
3710Sstevel@tonic-gate  *		char    d_name[MAXNAMLEN + 1];	* name no longer than this *
3720Sstevel@tonic-gate  *	};
3730Sstevel@tonic-gate  * are on the wire as:
3740Sstevel@tonic-gate  * union entlist (boolean valid) {
3750Sstevel@tonic-gate  * 	TRUE:	struct otw_dirent;
3760Sstevel@tonic-gate  *		uint_t nxtoffset;
3770Sstevel@tonic-gate  *		union entlist;
3780Sstevel@tonic-gate  *	FALSE:
3790Sstevel@tonic-gate  * }
3800Sstevel@tonic-gate  * where otw_dirent is:
3810Sstevel@tonic-gate  * 	struct dirent {
3820Sstevel@tonic-gate  *		uint_t	de_fid;
3830Sstevel@tonic-gate  *		string	de_name<AUTOFS_MAXPATHLEN>;
3840Sstevel@tonic-gate  *	}
3850Sstevel@tonic-gate  */
3860Sstevel@tonic-gate 
3870Sstevel@tonic-gate #ifdef nextdp
3880Sstevel@tonic-gate #undef nextdp
3890Sstevel@tonic-gate #endif
3900Sstevel@tonic-gate #define	nextdp(dp)	((struct dirent64 *)((char *)(dp) + (dp)->d_reclen))
3910Sstevel@tonic-gate 
3920Sstevel@tonic-gate /*
3930Sstevel@tonic-gate  * ENCODE ONLY
3940Sstevel@tonic-gate  */
3950Sstevel@tonic-gate bool_t
3960Sstevel@tonic-gate xdr_autofs_putrddirres(XDR *xdrs, struct autofsrddir *rddir, uint_t reqsize)
3970Sstevel@tonic-gate {
3980Sstevel@tonic-gate 	struct dirent64 *dp;
3990Sstevel@tonic-gate 	char *name;
4000Sstevel@tonic-gate 	int size;
4010Sstevel@tonic-gate 	uint_t namlen;
4020Sstevel@tonic-gate 	bool_t true = TRUE;
4030Sstevel@tonic-gate 	bool_t false = FALSE;
4040Sstevel@tonic-gate 	int entrysz;
4050Sstevel@tonic-gate 	int tofit;
4060Sstevel@tonic-gate 	int bufsize;
4070Sstevel@tonic-gate 	uint_t ino, off;
4080Sstevel@tonic-gate 
4090Sstevel@tonic-gate 	bufsize = 1 * BYTES_PER_XDR_UNIT;
4100Sstevel@tonic-gate 	for (size = rddir->rddir_size, dp = rddir->rddir_entries;
4110Sstevel@tonic-gate 		size > 0;
4120Sstevel@tonic-gate 		/* LINTED pointer alignment */
4130Sstevel@tonic-gate 		size -= dp->d_reclen, dp = nextdp(dp)) {
4140Sstevel@tonic-gate 		if (dp->d_reclen == 0 /* || DIRSIZ(dp) > dp->d_reclen */)
4150Sstevel@tonic-gate 			return (FALSE);
4160Sstevel@tonic-gate 		if (dp->d_ino == 0)
4170Sstevel@tonic-gate 			continue;
4180Sstevel@tonic-gate 		name = dp->d_name;
4190Sstevel@tonic-gate 		namlen = (uint_t)strlen(name);
4200Sstevel@tonic-gate 		ino = (uint_t)dp->d_ino;
4210Sstevel@tonic-gate 		off = (uint_t)dp->d_off;
4220Sstevel@tonic-gate 		entrysz = (1 + 1 + 1 + 1) * BYTES_PER_XDR_UNIT +
4230Sstevel@tonic-gate 		    roundup(namlen, BYTES_PER_XDR_UNIT);
4240Sstevel@tonic-gate 		tofit = entrysz + 2 * BYTES_PER_XDR_UNIT;
4250Sstevel@tonic-gate 		if (bufsize + tofit > reqsize) {
4260Sstevel@tonic-gate 			rddir->rddir_eof = FALSE;
4270Sstevel@tonic-gate 			break;
4280Sstevel@tonic-gate 		}
4290Sstevel@tonic-gate 		if (!xdr_bool(xdrs, &true) ||
4300Sstevel@tonic-gate 		    !xdr_u_int(xdrs, &ino) ||
4310Sstevel@tonic-gate 		    !xdr_bytes(xdrs, &name, &namlen, AUTOFS_MAXPATHLEN) ||
4320Sstevel@tonic-gate 		    !xdr_u_int(xdrs, &off)) {
4330Sstevel@tonic-gate 			return (FALSE);
4340Sstevel@tonic-gate 		}
4350Sstevel@tonic-gate 		bufsize += entrysz;
4360Sstevel@tonic-gate 	}
4370Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &false))
4380Sstevel@tonic-gate 		return (FALSE);
4390Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &rddir->rddir_eof))
4400Sstevel@tonic-gate 		return (FALSE);
4410Sstevel@tonic-gate 	return (TRUE);
4420Sstevel@tonic-gate }
4430Sstevel@tonic-gate 
4440Sstevel@tonic-gate 
4450Sstevel@tonic-gate /*
4460Sstevel@tonic-gate  * DECODE ONLY
4470Sstevel@tonic-gate  */
4480Sstevel@tonic-gate bool_t
4490Sstevel@tonic-gate xdr_autofs_getrddirres(XDR *xdrs, struct autofsrddir *rddir)
4500Sstevel@tonic-gate {
4510Sstevel@tonic-gate 	struct dirent64 *dp;
4520Sstevel@tonic-gate 	uint_t namlen;
4530Sstevel@tonic-gate 	int size;
4540Sstevel@tonic-gate 	bool_t valid;
4550Sstevel@tonic-gate 	uint_t offset;
4560Sstevel@tonic-gate 	uint_t fileid;
4570Sstevel@tonic-gate 
4580Sstevel@tonic-gate 	offset = (uint_t)-1;
4590Sstevel@tonic-gate 
4600Sstevel@tonic-gate 	size = rddir->rddir_size;
4610Sstevel@tonic-gate 	dp = rddir->rddir_entries;
4620Sstevel@tonic-gate 	for (;;) {
4630Sstevel@tonic-gate 		if (!xdr_bool(xdrs, &valid))
4640Sstevel@tonic-gate 			return (FALSE);
4650Sstevel@tonic-gate 		if (!valid)
4660Sstevel@tonic-gate 			break;
4670Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &fileid) ||
4680Sstevel@tonic-gate 		    !xdr_u_int(xdrs, &namlen))
4690Sstevel@tonic-gate 			return (FALSE);
4700Sstevel@tonic-gate 		if (DIRENT64_RECLEN(namlen) > size) {
4710Sstevel@tonic-gate 			rddir->rddir_eof = FALSE;
4720Sstevel@tonic-gate 			goto bufovflw;
4730Sstevel@tonic-gate 		}
4740Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, dp->d_name, namlen)||
4750Sstevel@tonic-gate 		    !xdr_u_int(xdrs, &offset))
4760Sstevel@tonic-gate 			return (FALSE);
4770Sstevel@tonic-gate 		dp->d_ino = fileid;
4780Sstevel@tonic-gate 		dp->d_reclen = (ushort_t)DIRENT64_RECLEN(namlen);
4790Sstevel@tonic-gate 		bzero(&dp->d_name[namlen],
4800Sstevel@tonic-gate 		    DIRENT64_NAMELEN(dp->d_reclen) - namlen);
4810Sstevel@tonic-gate 		dp->d_off = offset;
4820Sstevel@tonic-gate 		size -= dp->d_reclen;
4830Sstevel@tonic-gate 		/* LINTED pointer alignment */
4840Sstevel@tonic-gate 		dp = nextdp(dp);
4850Sstevel@tonic-gate 	}
4860Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &rddir->rddir_eof))
4870Sstevel@tonic-gate 		return (FALSE);
4880Sstevel@tonic-gate bufovflw:
4890Sstevel@tonic-gate 	rddir->rddir_size = (uint_t)((char *)dp - (char *)rddir->rddir_entries);
4900Sstevel@tonic-gate 	rddir->rddir_offset = offset;
4910Sstevel@tonic-gate 	return (TRUE);
4920Sstevel@tonic-gate }
4930Sstevel@tonic-gate 
4940Sstevel@tonic-gate bool_t
4950Sstevel@tonic-gate xdr_autofs_rddirres(XDR *xdrs, autofs_rddirres *objp)
4960Sstevel@tonic-gate {
4970Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->rd_status))
4980Sstevel@tonic-gate 		return (FALSE);
4990Sstevel@tonic-gate 	if (objp->rd_status != AUTOFS_OK)
5000Sstevel@tonic-gate 		return (TRUE);
5010Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE)
5020Sstevel@tonic-gate 		return (xdr_autofs_putrddirres(xdrs,
5030Sstevel@tonic-gate 		    (struct autofsrddir *)&objp->rd_rddir, objp->rd_bufsize));
5040Sstevel@tonic-gate 	else if (xdrs->x_op == XDR_DECODE)
5050Sstevel@tonic-gate 		return (xdr_autofs_getrddirres(xdrs,
5060Sstevel@tonic-gate 		    (struct autofsrddir *)&objp->rd_rddir));
5070Sstevel@tonic-gate 	return (FALSE);
5080Sstevel@tonic-gate }
509