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