xref: /illumos-gate/usr/src/cmd/fs.d/autofs/autod_xdr.c (revision 7c478bd9)
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  *	autod_xdr.c
24  *
25  *	Copyright 1999, 2002 Sun Microsystems, Inc.  All rights reserved.
26  *	Use is subject to license terms.
27  */
28 
29 #pragma ident	"%Z%%M%	%I%	%E% SMI"
30 
31 /*
32  * This file can not be automatically generated by rpcgen from
33  * autofs_prot.x because of the xdr routines that provide readdir
34  * support, and my own implementation of xdr_autofs_netbuf().
35  */
36 
37 #include <sys/vfs.h>
38 #include <sys/sysmacros.h>		/* includes roundup() */
39 #include <string.h>
40 #include <rpcsvc/autofs_prot.h>
41 #include <rpc/xdr.h>
42 
43 bool_t
44 xdr_autofs_stat(register XDR *xdrs, autofs_stat *objp)
45 {
46 	if (!xdr_enum(xdrs, (enum_t *)objp))
47 		return (FALSE);
48 	return (TRUE);
49 }
50 
51 bool_t
52 xdr_autofs_action(register XDR *xdrs, autofs_action *objp)
53 {
54 	if (!xdr_enum(xdrs, (enum_t *)objp))
55 		return (FALSE);
56 	return (TRUE);
57 }
58 
59 bool_t
60 xdr_linka(register XDR *xdrs, linka *objp)
61 {
62 	if (!xdr_string(xdrs, &objp->dir, AUTOFS_MAXPATHLEN))
63 		return (FALSE);
64 	if (!xdr_string(xdrs, &objp->link, AUTOFS_MAXPATHLEN))
65 		return (FALSE);
66 	return (TRUE);
67 }
68 
69 bool_t
70 xdr_autofs_netbuf(xdrs, objp)
71 	XDR *xdrs;
72 	struct netbuf *objp;
73 {
74 	bool_t dummy;
75 
76 	if (!xdr_u_int(xdrs, &objp->maxlen)) {
77 		return (FALSE);
78 	}
79 	dummy = xdr_bytes(xdrs, (char **)&(objp->buf),
80 			(u_int *)&(objp->len), objp->maxlen);
81 	return (dummy);
82 }
83 
84 bool_t
85 xdr_autofs_args(register XDR *xdrs, autofs_args *objp)
86 {
87 	if (!xdr_autofs_netbuf(xdrs, &objp->addr))
88 		return (FALSE);
89 	if (!xdr_string(xdrs, &objp->path, AUTOFS_MAXPATHLEN))
90 		return (FALSE);
91 	if (!xdr_string(xdrs, &objp->opts, AUTOFS_MAXOPTSLEN))
92 		return (FALSE);
93 	if (!xdr_string(xdrs, &objp->map, AUTOFS_MAXPATHLEN))
94 		return (FALSE);
95 	if (!xdr_string(xdrs, &objp->subdir, AUTOFS_MAXPATHLEN))
96 		return (FALSE);
97 	if (!xdr_string(xdrs, &objp->key, AUTOFS_MAXCOMPONENTLEN))
98 		return (FALSE);
99 	if (!xdr_int(xdrs, &objp->mount_to))
100 		return (FALSE);
101 	if (!xdr_int(xdrs, &objp->rpc_to))
102 		return (FALSE);
103 	if (!xdr_int(xdrs, &objp->direct))
104 		return (FALSE);
105 	return (TRUE);
106 }
107 
108 bool_t
109 xdr_mounta(register XDR *xdrs, struct mounta *objp)
110 {
111 	if (!xdr_string(xdrs, &objp->spec, AUTOFS_MAXPATHLEN))
112 		return (FALSE);
113 	if (!xdr_string(xdrs, &objp->dir, AUTOFS_MAXPATHLEN))
114 		return (FALSE);
115 	if (!xdr_int(xdrs, &objp->flags))
116 		return (FALSE);
117 	if (!xdr_string(xdrs, &objp->fstype, AUTOFS_MAXCOMPONENTLEN))
118 		return (FALSE);
119 	if (!xdr_pointer(xdrs, (char **)&objp->dataptr, sizeof (autofs_args),
120 	    (xdrproc_t) xdr_autofs_args))
121 		return (FALSE);
122 	if (!xdr_int(xdrs, &objp->datalen))
123 		return (FALSE);
124 	if (!xdr_string(xdrs, &objp->optptr, AUTOFS_MAXOPTSLEN))
125 		return (FALSE);
126 	if (!xdr_int(xdrs, &objp->optlen))
127 		return (FALSE);
128 	return (TRUE);
129 }
130 
131 bool_t
132 xdr_action_list_entry(register XDR *xdrs, action_list_entry *objp)
133 {
134 	if (!xdr_autofs_action(xdrs, &objp->action))
135 		return (FALSE);
136 	switch (objp->action) {
137 	case AUTOFS_MOUNT_RQ:
138 		if (!xdr_mounta(xdrs, &objp->action_list_entry_u.mounta))
139 			return (FALSE);
140 		break;
141 	case AUTOFS_LINK_RQ:
142 		if (!xdr_linka(xdrs, &objp->action_list_entry_u.linka))
143 			return (FALSE);
144 		break;
145 	}
146 	return (TRUE);
147 }
148 
149 bool_t
150 xdr_action_list(register XDR *xdrs, action_list *objp)
151 {
152 	if (!xdr_action_list_entry(xdrs, &objp->action))
153 		return (FALSE);
154 	if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (action_list),
155 			(xdrproc_t) xdr_action_list))
156 		return (FALSE);
157 	return (TRUE);
158 }
159 
160 bool_t
161 xdr_umntrequest(register XDR *xdrs, umntrequest *objp)
162 {
163 	if (!xdr_bool_t(xdrs, &objp->isdirect))
164 		return (FALSE);
165 	if (!xdr_string(xdrs, &objp->mntresource, AUTOFS_MAXPATHLEN))
166 		return (FALSE);
167 	if (!xdr_string(xdrs, &objp->mntpnt, AUTOFS_MAXPATHLEN))
168 		return (FALSE);
169 	if (!xdr_string(xdrs, &objp->fstype, AUTOFS_MAXCOMPONENTLEN))
170 		return (FALSE);
171 	if (!xdr_string(xdrs, &objp->mntopts, AUTOFS_MAXOPTSLEN))
172 		return (FALSE);
173 	if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (umntrequest),
174 			(xdrproc_t) xdr_umntrequest))
175 		return (FALSE);
176 	return (TRUE);
177 }
178 
179 bool_t
180 xdr_umntres(register XDR *xdrs, umntres *objp)
181 {
182 	if (!xdr_int(xdrs, &objp->status))
183 		return (FALSE);
184 	return (TRUE);
185 }
186 
187 bool_t
188 xdr_autofs_res(xdrs, objp)
189 	register XDR *xdrs;
190 	autofs_res *objp;
191 {
192 	if (!xdr_enum(xdrs, (enum_t *)objp))
193 		return (FALSE);
194 	return (TRUE);
195 }
196 
197 bool_t
198 xdr_autofs_lookupargs(xdrs, objp)
199 	register XDR *xdrs;
200 	autofs_lookupargs *objp;
201 {
202 	if (!xdr_string(xdrs, &objp->map, AUTOFS_MAXPATHLEN))
203 		return (FALSE);
204 	if (!xdr_string(xdrs, &objp->path, AUTOFS_MAXPATHLEN))
205 		return (FALSE);
206 	if (!xdr_string(xdrs, &objp->name, AUTOFS_MAXCOMPONENTLEN))
207 		return (FALSE);
208 	if (!xdr_string(xdrs, &objp->subdir, AUTOFS_MAXPATHLEN))
209 		return (FALSE);
210 	if (!xdr_string(xdrs, &objp->opts, AUTOFS_MAXOPTSLEN))
211 		return (FALSE);
212 	if (!xdr_bool_t(xdrs, &objp->isdirect))
213 		return (FALSE);
214 	return (TRUE);
215 }
216 
217 bool_t
218 xdr_mount_result_type(xdrs, objp)
219 	register XDR *xdrs;
220 	mount_result_type *objp;
221 {
222 	if (!xdr_autofs_stat(xdrs, &objp->status))
223 		return (FALSE);
224 	switch (objp->status) {
225 	case AUTOFS_ACTION:
226 		if (!xdr_pointer(xdrs,
227 		    (char **)&objp->mount_result_type_u.list,
228 		    sizeof (action_list), (xdrproc_t) xdr_action_list))
229 			return (FALSE);
230 		break;
231 	case AUTOFS_DONE:
232 		if (!xdr_int(xdrs, &objp->mount_result_type_u.error))
233 			return (FALSE);
234 		break;
235 	}
236 	return (TRUE);
237 }
238 
239 bool_t
240 xdr_autofs_mountres(xdrs, objp)
241 	register XDR *xdrs;
242 	autofs_mountres *objp;
243 {
244 	if (!xdr_mount_result_type(xdrs, &objp->mr_type))
245 		return (FALSE);
246 	if (!xdr_int(xdrs, &objp->mr_verbose))
247 		return (FALSE);
248 	return (TRUE);
249 }
250 bool_t
251 xdr_lookup_result_type(xdrs, objp)
252 	register XDR *xdrs;
253 	lookup_result_type *objp;
254 {
255 	if (!xdr_autofs_action(xdrs, &objp->action))
256 		return (FALSE);
257 	switch (objp->action) {
258 	case AUTOFS_LINK_RQ:
259 		if (!xdr_linka(xdrs, &objp->lookup_result_type_u.lt_linka))
260 			return (FALSE);
261 		break;
262 	}
263 	return (TRUE);
264 }
265 
266 bool_t
267 xdr_autofs_lookupres(xdrs, objp)
268 	register XDR *xdrs;
269 	autofs_lookupres *objp;
270 {
271 	if (!xdr_autofs_res(xdrs, &objp->lu_res))
272 		return (FALSE);
273 	if (!xdr_lookup_result_type(xdrs, &objp->lu_type))
274 		return (FALSE);
275 	if (!xdr_int(xdrs, &objp->lu_verbose))
276 		return (FALSE);
277 	return (TRUE);
278 }
279 
280 /*
281  * ******************************************************
282  * Readdir XDR support
283  * ******************************************************
284  */
285 
286 bool_t
287 xdr_autofs_rddirargs(xdrs, objp)
288 	register XDR *xdrs;
289 	autofs_rddirargs *objp;
290 {
291 	if (!xdr_string(xdrs, &objp->rda_map, AUTOFS_MAXPATHLEN))
292 		return (FALSE);
293 	if (!xdr_u_int(xdrs, &objp->rda_offset))
294 		return (FALSE);
295 	if (!xdr_u_int(xdrs, &objp->rda_count))
296 		return (FALSE);
297 	return (TRUE);
298 }
299 
300 /*
301  * Directory read reply:
302  * union (enum autofs_res) {
303  *	AUTOFS_OK: entlist;
304  *		 boolean eof;
305  *	default:
306  * }
307  *
308  * Directory entries
309  *	struct  direct {
310  *		off_t   d_off;			* offset of next entry *
311  *		u_long  d_fileno;		* inode number of entry *
312  *		u_short d_reclen;		* length of this record *
313  *		u_short d_namlen;		* length of string in d_name *
314  *		char    d_name[MAXNAMLEN + 1];	* name no longer than this *
315  *	};
316  * are on the wire as:
317  * union entlist (boolean valid) {
318  * 	TRUE:	struct otw_dirent;
319  *		u_long nxtoffset;
320  *		union entlist;
321  *	FALSE:
322  * }
323  * where otw_dirent is:
324  * 	struct dirent {
325  *		u_long	de_fid;
326  *		string	de_name<AUTOFS_MAXPATHLEN>;
327  *	}
328  */
329 
330 #ifdef nextdp
331 #undef nextdp
332 #endif
333 #define	nextdp(dp)	((struct dirent64 *)((char *)(dp) + (dp)->d_reclen))
334 
335 /*
336  * ENCODE ONLY
337  */
338 bool_t
339 xdr_autofs_putrddirres(xdrs, rddir, reqsize)
340 	XDR *xdrs;
341 	struct autofsrddir *rddir;
342 	uint_t reqsize;			/* requested size */
343 {
344 	struct dirent64 *dp;
345 	char *name;
346 	int size;
347 	u_int namlen;
348 	bool_t true = TRUE;
349 	bool_t false = FALSE;
350 	int entrysz;
351 	int tofit;
352 	int bufsize;
353 	uint_t ino, off;
354 
355 	bufsize = 1 * BYTES_PER_XDR_UNIT;
356 	for (size = rddir->rddir_size, dp = rddir->rddir_entries;
357 		size > 0;
358 		/* LINTED pointer alignment */
359 		size -= dp->d_reclen, dp = nextdp(dp)) {
360 		if (dp->d_reclen == 0 /* || DIRSIZ(dp) > dp->d_reclen */) {
361 			return (FALSE);
362 		}
363 		if (dp->d_ino == 0) {
364 			continue;
365 		}
366 		name = dp->d_name;
367 		namlen = strlen(name);
368 		ino = (uint_t) dp->d_ino;
369 		off = (uint_t) dp->d_off;
370 		entrysz = (1 + 1 + 1 + 1) * BYTES_PER_XDR_UNIT +
371 		    roundup(namlen, BYTES_PER_XDR_UNIT);
372 		tofit = entrysz + 2 * BYTES_PER_XDR_UNIT;
373 		if (bufsize + tofit > reqsize) {
374 			rddir->rddir_eof = FALSE;
375 			break;
376 		}
377 		if (!xdr_bool(xdrs, &true) ||
378 		    !xdr_u_int(xdrs, &ino) ||
379 		    !xdr_bytes(xdrs, &name, &namlen, AUTOFS_MAXPATHLEN) ||
380 		    !xdr_u_int(xdrs, &off)) {
381 			return (FALSE);
382 		}
383 		bufsize += entrysz;
384 	}
385 	if (!xdr_bool(xdrs, &false)) {
386 		return (FALSE);
387 	}
388 	if (!xdr_bool(xdrs, &rddir->rddir_eof)) {
389 		return (FALSE);
390 	}
391 	return (TRUE);
392 }
393 
394 #define	DIRENT64_RECLEN(namelen)	\
395 	(((int)(((dirent64_t *)0)->d_name) + 1 + (namelen) + 7) & ~ 7)
396 #define	reclen(namlen)	DIRENT64_RECLEN((namlen))
397 
398 /*
399  * DECODE ONLY
400  */
401 bool_t
402 xdr_autofs_getrddirres(xdrs, rddir)
403 	XDR *xdrs;
404 	struct autofsrddir *rddir;
405 {
406 	struct dirent64 *dp;
407 	uint namlen;
408 	int size;
409 	bool_t valid;
410 	int offset = -1;
411 	uint_t fileid;
412 
413 	size = rddir->rddir_size;
414 	dp = rddir->rddir_entries;
415 	for (;;) {
416 		if (!xdr_bool(xdrs, &valid)) {
417 			return (FALSE);
418 		}
419 		if (!valid) {
420 			break;
421 		}
422 		if (!xdr_u_int(xdrs, &fileid) ||
423 		    !xdr_u_int(xdrs, &namlen)) {
424 			return (FALSE);
425 		}
426 		if (reclen(namlen) > size) {
427 			rddir->rddir_eof = FALSE;
428 			goto bufovflw;
429 		}
430 		if (!xdr_opaque(xdrs, dp->d_name, namlen)||
431 		    !xdr_int(xdrs, &offset)) {
432 			return (FALSE);
433 		}
434 		dp->d_ino = fileid;
435 		dp->d_reclen = reclen(namlen);
436 		dp->d_name[namlen] = '\0';
437 		dp->d_off = offset;
438 		size -= dp->d_reclen;
439 		/* LINTED pointer alignment */
440 		dp = nextdp(dp);
441 	}
442 	if (!xdr_bool(xdrs, &rddir->rddir_eof)) {
443 		return (FALSE);
444 	}
445 bufovflw:
446 	rddir->rddir_size = (char *)dp - (char *)(rddir->rddir_entries);
447 	rddir->rddir_offset = offset;
448 	return (TRUE);
449 }
450 
451 bool_t
452 xdr_autofs_rddirres(register XDR *xdrs, autofs_rddirres *objp)
453 {
454 	if (!xdr_enum(xdrs, (enum_t *)&objp->rd_status))
455 		return (FALSE);
456 	if (objp->rd_status != AUTOFS_OK)
457 		return (TRUE);
458 	if (xdrs->x_op == XDR_ENCODE)
459 		return (xdr_autofs_putrddirres(
460 			xdrs, (struct autofsrddir *)&objp->rd_rddir,
461 			objp->rd_bufsize));
462 	else if (xdrs->x_op == XDR_DECODE)
463 		return (xdr_autofs_getrddirres(xdrs,
464 			(struct autofsrddir *)&objp->rd_rddir));
465 	else return (FALSE);
466 }
467