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 #include <stdio.h>				/* for fprintf() */
28 #include <stdlib.h>				/* for malloc() */
29 #include <rpc/types.h>
30 #include <rpc/xdr.h>
31 #include <rpcsvc/mount.h>
32 
33 
34 /*
35  * XDR routines to handle mountlist structure
36  *
37  * These are iterative versions to avoid the stack-blowing problems of
38  * the recursive routines generated by rpcgen.
39  *
40  * XXXX These should be removed when rpcgen is fixed to produce better
41  * code in these circumstances.
42  */
43 
44 
45 bool_t
xdr_mountlist(xdrs,objp)46 xdr_mountlist(xdrs, objp)
47 	register XDR *xdrs;
48 	mountlist *objp;
49 {
50 	bool_t more_data;
51 
52 	switch (xdrs->x_op) {
53 
54 	case XDR_FREE: {
55 		mountbody *mb, *tmp;
56 
57 		tmp = *objp;
58 
59 		while (tmp != NULL) {
60 			mb = tmp;
61 			tmp = mb->ml_next;
62 			if (!xdr_name(xdrs, &mb->ml_hostname))
63 				return (FALSE);
64 			if (!xdr_dirpath(xdrs, &mb->ml_directory))
65 				return (FALSE);
66 			free(mb);
67 		}
68 
69 		break;
70 	}
71 
72 	case XDR_DECODE: {
73 		mountbody *mb;
74 		mountbody *mb_prev = NULL;
75 
76 		for (;;) {
77 			if (!xdr_bool(xdrs, &more_data))
78 				return (FALSE);
79 
80 			if (!more_data)
81 				break;
82 
83 			mb = (mountbody *)malloc(sizeof (struct mountbody));
84 			if (mb == NULL) {
85 				fprintf(stderr,
86 				    "xdr_mountlist: out of memory\n");
87 				return (FALSE);
88 			}
89 			mb->ml_hostname = NULL;
90 			mb->ml_directory = NULL;
91 			mb->ml_next = NULL;
92 
93 			if (mb_prev == NULL) {
94 				mb_prev = mb;
95 				*objp = mb;
96 			}
97 
98 			if (!xdr_name(xdrs, &mb->ml_hostname))
99 				return (FALSE);
100 			if (!xdr_dirpath(xdrs, &mb->ml_directory))
101 				return (FALSE);
102 
103 			if (mb_prev != mb) {
104 				mb_prev->ml_next = mb;
105 				mb_prev = mb;
106 			}
107 		}
108 		break;
109 	}
110 
111 	case XDR_ENCODE: {
112 		mountbody *mb;
113 
114 		mb = *objp;
115 
116 		for (;;) {
117 			more_data = mb != NULL;
118 
119 			if (!xdr_bool(xdrs, &more_data))
120 				return (FALSE);
121 
122 			if (!more_data)
123 				break;
124 
125 			if (!xdr_name(xdrs, &mb->ml_hostname))
126 				return (FALSE);
127 			if (!xdr_dirpath(xdrs, &mb->ml_directory))
128 				return (FALSE);
129 
130 			mb = mb->ml_next;
131 		}
132 		break;
133 	}
134 
135 	default:
136 		break;
137 	}
138 
139 	return (TRUE);
140 }
141 
142 
143 /*
144  * xdr_mountbody() is included here simply for backward compatibility. It is
145  * no longer used by xdr_mountlist(), nor by any other SunOS routine as of
146  * now.
147  *
148  * This is simply a copy of the rpcgen generated routine.
149  */
150 bool_t
xdr_mountbody(xdrs,objp)151 xdr_mountbody(xdrs, objp)
152 	register XDR *xdrs;
153 	mountbody *objp;
154 {
155 	if (!xdr_name(xdrs, &objp->ml_hostname))
156 		return (FALSE);
157 	if (!xdr_dirpath(xdrs, &objp->ml_directory))
158 		return (FALSE);
159 	if (!xdr_mountlist(xdrs, &objp->ml_next))
160 		return (FALSE);
161 	return (TRUE);
162 }
163