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