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