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 #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 } 514