1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright (c) 1998 by Sun Microsystems, Inc.
24 * All rights reserved.
25 */
26
27
28#pragma ident	"%Z%%M%	%I%	%E% SMI"
29
30
31#include <stdio.h>				/* for fprintf() */
32#include <stdlib.h>				/* for malloc() */
33#include <rpc/types.h>
34#include <rpc/xdr.h>
35#include <rpcsvc/mount.h>
36
37
38/*
39 * XDR routines to handle mountlist structure
40 *
41 * These are iterative versions to avoid the stack-blowing problems of
42 * the recursive routines generated by rpcgen.
43 *
44 * XXXX These should be removed when rpcgen is fixed to produce better
45 * code in these circumstances.
46 */
47
48
49bool_t
50xdr_mountlist(xdrs, objp)
51	register XDR *xdrs;
52	mountlist *objp;
53{
54	bool_t more_data;
55
56	switch (xdrs->x_op) {
57
58	case XDR_FREE: {
59		mountbody *mb, *tmp;
60
61		tmp = *objp;
62
63		while (tmp != NULL) {
64			mb = tmp;
65			tmp = mb->ml_next;
66			if (!xdr_name(xdrs, &mb->ml_hostname))
67				return (FALSE);
68			if (!xdr_dirpath(xdrs, &mb->ml_directory))
69				return (FALSE);
70			free(mb);
71		}
72
73		break;
74	}
75
76	case XDR_DECODE: {
77		mountbody *mb;
78		mountbody *mb_prev = NULL;
79
80		for (;;) {
81			if (!xdr_bool(xdrs, &more_data))
82				return (FALSE);
83
84			if (!more_data)
85				break;
86
87			mb = (mountbody *)malloc(sizeof (struct mountbody));
88			if (mb == NULL) {
89				fprintf(stderr,
90				    "xdr_mountlist: out of memory\n");
91				return (FALSE);
92			}
93			mb->ml_hostname = NULL;
94			mb->ml_directory = NULL;
95			mb->ml_next = NULL;
96
97			if (mb_prev == NULL) {
98				mb_prev = mb;
99				*objp = mb;
100			}
101
102			if (!xdr_name(xdrs, &mb->ml_hostname))
103				return (FALSE);
104			if (!xdr_dirpath(xdrs, &mb->ml_directory))
105				return (FALSE);
106
107			if (mb_prev != mb) {
108				mb_prev->ml_next = mb;
109				mb_prev = mb;
110			}
111		}
112		break;
113	}
114
115	case XDR_ENCODE: {
116		mountbody *mb;
117
118		mb = *objp;
119
120		for (;;) {
121			more_data = mb != NULL;
122
123			if (!xdr_bool(xdrs, &more_data))
124				return (FALSE);
125
126			if (!more_data)
127				break;
128
129			if (!xdr_name(xdrs, &mb->ml_hostname))
130				return (FALSE);
131			if (!xdr_dirpath(xdrs, &mb->ml_directory))
132				return (FALSE);
133
134			mb = mb->ml_next;
135		}
136		break;
137	}
138
139	default:
140		break;
141	}
142
143	return (TRUE);
144}
145
146
147/*
148 * xdr_mountbody() is included here simply for backward compatibility. It is
149 * no longer used by xdr_mountlist(), nor by any other SunOS routine as of
150 * now.
151 *
152 * This is simply a copy of the rpcgen generated routine.
153 */
154bool_t
155xdr_mountbody(xdrs, objp)
156	register XDR *xdrs;
157	mountbody *objp;
158{
159	if (!xdr_name(xdrs, &objp->ml_hostname))
160		return (FALSE);
161	if (!xdr_dirpath(xdrs, &objp->ml_directory))
162		return (FALSE);
163	if (!xdr_mountlist(xdrs, &objp->ml_next))
164		return (FALSE);
165	return (TRUE);
166}
167