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