0
|
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 "@(#)autod_xdr.c 1.41 07/08/27 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 #include <stdlib.h>
|
|
42 #include <strings.h>
|
|
43
|
|
44 bool_t
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 }
|