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