xref: /illumos-gate/usr/src/cmd/fs.d/autofs/autod_xdr.c (revision 39d3e169)
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 2006 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 	return (TRUE);
214 }
215 
216 bool_t
217 xdr_mount_result_type(xdrs, objp)
218 	register XDR *xdrs;
219 	mount_result_type *objp;
220 {
221 	if (!xdr_autofs_stat(xdrs, &objp->status))
222 		return (FALSE);
223 	switch (objp->status) {
224 	case AUTOFS_ACTION:
225 		if (!xdr_pointer(xdrs,
226 		    (char **)&objp->mount_result_type_u.list,
227 		    sizeof (action_list), (xdrproc_t)xdr_action_list))
228 			return (FALSE);
229 		break;
230 	case AUTOFS_DONE:
231 		if (!xdr_int(xdrs, &objp->mount_result_type_u.error))
232 			return (FALSE);
233 		break;
234 	}
235 	return (TRUE);
236 }
237 
238 bool_t
239 xdr_autofs_mountres(xdrs, objp)
240 	register XDR *xdrs;
241 	autofs_mountres *objp;
242 {
243 	if (!xdr_mount_result_type(xdrs, &objp->mr_type))
244 		return (FALSE);
245 	if (!xdr_int(xdrs, &objp->mr_verbose))
246 		return (FALSE);
247 	return (TRUE);
248 }
249 bool_t
250 xdr_lookup_result_type(xdrs, objp)
251 	register XDR *xdrs;
252 	lookup_result_type *objp;
253 {
254 	if (!xdr_autofs_action(xdrs, &objp->action))
255 		return (FALSE);
256 	switch (objp->action) {
257 	case AUTOFS_LINK_RQ:
258 		if (!xdr_linka(xdrs, &objp->lookup_result_type_u.lt_linka))
259 			return (FALSE);
260 		break;
261 	}
262 	return (TRUE);
263 }
264 
265 bool_t
266 xdr_autofs_lookupres(xdrs, objp)
267 	register XDR *xdrs;
268 	autofs_lookupres *objp;
269 {
270 	if (!xdr_autofs_res(xdrs, &objp->lu_res))
271 		return (FALSE);
272 	if (!xdr_lookup_result_type(xdrs, &objp->lu_type))
273 		return (FALSE);
274 	if (!xdr_int(xdrs, &objp->lu_verbose))
275 		return (FALSE);
276 	return (TRUE);
277 }
278 
279 /*
280  * ******************************************************
281  * Readdir XDR support
282  * ******************************************************
283  */
284 
285 bool_t
286 xdr_autofs_rddirargs(xdrs, objp)
287 	register XDR *xdrs;
288 	autofs_rddirargs *objp;
289 {
290 	if (!xdr_string(xdrs, &objp->rda_map, AUTOFS_MAXPATHLEN))
291 		return (FALSE);
292 	if (!xdr_u_int(xdrs, &objp->rda_offset))
293 		return (FALSE);
294 	if (!xdr_u_int(xdrs, &objp->rda_count))
295 		return (FALSE);
296 	return (TRUE);
297 }
298 
299 /*
300  * Directory read reply:
301  * union (enum autofs_res) {
302  *	AUTOFS_OK: entlist;
303  *		 boolean eof;
304  *	default:
305  * }
306  *
307  * Directory entries
308  *	struct  direct {
309  *		off_t   d_off;			* offset of next entry *
310  *		u_long  d_fileno;		* inode number of entry *
311  *		u_short d_reclen;		* length of this record *
312  *		u_short d_namlen;		* length of string in d_name *
313  *		char    d_name[MAXNAMLEN + 1];	* name no longer than this *
314  *	};
315  * are on the wire as:
316  * union entlist (boolean valid) {
317  * 	TRUE:	struct otw_dirent;
318  *		u_long nxtoffset;
319  *		union entlist;
320  *	FALSE:
321  * }
322  * where otw_dirent is:
323  * 	struct dirent {
324  *		u_long	de_fid;
325  *		string	de_name<AUTOFS_MAXPATHLEN>;
326  *	}
327  */
328 
329 #ifdef nextdp
330 #undef nextdp
331 #endif
332 #define	nextdp(dp)	((struct dirent64 *)((char *)(dp) + (dp)->d_reclen))
333 
334 /*
335  * ENCODE ONLY
336  */
337 bool_t
338 xdr_autofs_putrddirres(xdrs, rddir, reqsize)
339 	XDR *xdrs;
340 	struct autofsrddir *rddir;
341 	uint_t reqsize;			/* requested size */
342 {
343 	struct dirent64 *dp;
344 	char *name;
345 	int size;
346 	uint_t namlen;
347 	bool_t true = TRUE;
348 	bool_t false = FALSE;
349 	int entrysz;
350 	int tofit;
351 	int bufsize;
352 	uint_t ino, off;
353 
354 	bufsize = 1 * BYTES_PER_XDR_UNIT;
355 	for (size = rddir->rddir_size, dp = rddir->rddir_entries;
356 		size > 0;
357 		/* LINTED pointer alignment */
358 		size -= dp->d_reclen, dp = nextdp(dp)) {
359 		if (dp->d_reclen == 0 /* || DIRSIZ(dp) > dp->d_reclen */) {
360 			return (FALSE);
361 		}
362 		if (dp->d_ino == 0) {
363 			continue;
364 		}
365 		name = dp->d_name;
366 		namlen = strlen(name);
367 		ino = (uint_t)dp->d_ino;
368 		off = (uint_t)dp->d_off;
369 		entrysz = (1 + 1 + 1 + 1) * BYTES_PER_XDR_UNIT +
370 		    roundup(namlen, BYTES_PER_XDR_UNIT);
371 		tofit = entrysz + 2 * BYTES_PER_XDR_UNIT;
372 		if (bufsize + tofit > reqsize) {
373 			rddir->rddir_eof = FALSE;
374 			break;
375 		}
376 		if (!xdr_bool(xdrs, &true) ||
377 		    !xdr_u_int(xdrs, &ino) ||
378 		    !xdr_bytes(xdrs, &name, &namlen, AUTOFS_MAXPATHLEN) ||
379 		    !xdr_u_int(xdrs, &off)) {
380 			return (FALSE);
381 		}
382 		bufsize += entrysz;
383 	}
384 	if (!xdr_bool(xdrs, &false)) {
385 		return (FALSE);
386 	}
387 	if (!xdr_bool(xdrs, &rddir->rddir_eof)) {
388 		return (FALSE);
389 	}
390 	return (TRUE);
391 }
392 
393 #define	DIRENT64_RECLEN(namelen)	\
394 	(((int)(((dirent64_t *)0)->d_name) + 1 + (namelen) + 7) & ~ 7)
395 #define	reclen(namlen)	DIRENT64_RECLEN((namlen))
396 
397 /*
398  * DECODE ONLY
399  */
400 bool_t
401 xdr_autofs_getrddirres(xdrs, rddir)
402 	XDR *xdrs;
403 	struct autofsrddir *rddir;
404 {
405 	struct dirent64 *dp;
406 	uint_t namlen;
407 	int size;
408 	bool_t valid;
409 	int offset = -1;
410 	uint_t fileid;
411 
412 	size = rddir->rddir_size;
413 	dp = rddir->rddir_entries;
414 	for (;;) {
415 		if (!xdr_bool(xdrs, &valid)) {
416 			return (FALSE);
417 		}
418 		if (!valid) {
419 			break;
420 		}
421 		if (!xdr_u_int(xdrs, &fileid) ||
422 		    !xdr_u_int(xdrs, &namlen)) {
423 			return (FALSE);
424 		}
425 		if (reclen(namlen) > size) {
426 			rddir->rddir_eof = FALSE;
427 			goto bufovflw;
428 		}
429 		if (!xdr_opaque(xdrs, dp->d_name, namlen)||
430 		    !xdr_int(xdrs, &offset)) {
431 			return (FALSE);
432 		}
433 		dp->d_ino = fileid;
434 		dp->d_reclen = reclen(namlen);
435 		dp->d_name[namlen] = '\0';
436 		dp->d_off = offset;
437 		size -= dp->d_reclen;
438 		/* LINTED pointer alignment */
439 		dp = nextdp(dp);
440 	}
441 	if (!xdr_bool(xdrs, &rddir->rddir_eof)) {
442 		return (FALSE);
443 	}
444 bufovflw:
445 	rddir->rddir_size = (char *)dp - (char *)(rddir->rddir_entries);
446 	rddir->rddir_offset = offset;
447 	return (TRUE);
448 }
449 
450 bool_t
451 xdr_autofs_rddirres(register XDR *xdrs, autofs_rddirres *objp)
452 {
453 	if (!xdr_enum(xdrs, (enum_t *)&objp->rd_status))
454 		return (FALSE);
455 	if (objp->rd_status != AUTOFS_OK)
456 		return (TRUE);
457 	if (xdrs->x_op == XDR_ENCODE)
458 		return (xdr_autofs_putrddirres(
459 			xdrs, (struct autofsrddir *)&objp->rd_rddir,
460 			objp->rd_bufsize));
461 	else if (xdrs->x_op == XDR_DECODE)
462 		return (xdr_autofs_getrddirres(xdrs,
463 			(struct autofsrddir *)&objp->rd_rddir));
464 	else return (FALSE);
465 }
466