static bool xdr_putentry (XDR *x, afsnode *n, filename name, u_int32_t cookie) { return // entry * (non-null): xdr_putint (x, 1) // u_int fileid: && xdr_putint (x, n->ino) // filename name: && xdr_filename (x, &name) // nfscookie cookie: && xdr_putint (x, cookie); }
/* * An external data representation format for MP_INTs. * * This is basically the same as opaque XDR data: Size followed by * data followed by padding. However, the encoded size is always * chosen to be a multiple of 4, so so the padding is never used. * * The external representation has the following three parts: * * size: 4-byte big-endian word indicating the number of bytes * used to encode the number. The ENCODE operation rounds * this up to the next multiple of 4. * * number: a size byte, 2's complement represantation of the MP_INT * (The most significant bit is the sign bit. The number * -1 is represented by size bytes of value 0xff - where * size would most likely be 1.) * * padding: (4 - size) % 4 bytes of padding to make the whole thing * a multiple of four bytes. (Since size is 0 bytes, the * encoding will always have a zero-length padding.) */ bool_t xdr_mpz_t (register XDR *xdrs, MP_INT *z) { u_int32_t size; char *cp; switch (xdrs->x_op) { case XDR_ENCODE: size = (mpz_rawsize (z) + 3) & ~3; if (!xdr_putint (xdrs, size)) return FALSE; if (!(cp = (char *) XDR_INLINE (xdrs, size))) return FALSE; mpz_get_raw (cp, size, z); break; case XDR_DECODE: if (!z->_mp_d) mpz_init (z); if (!xdr_getint (xdrs, size) || (int32_t) size < 0) return FALSE; if (!(cp = (char *) XDR_INLINE (xdrs, (size + 3) & ~3))) return FALSE; mpz_set_raw (z, cp, size); break; case XDR_FREE: if (z->_mp_d) mpz_clear (z); z->_mp_d = NULL; } return TRUE; }
int authuint_marshal (AUTH *auth, XDR *x) { if (u_int32_t *dp = (u_int32_t *) XDR_INLINE (x, 5*4)) { dp[0] = htonl (AUTH_UINT); dp[1] = htonl (4); dp[2] = htonl (auth->ah_key.key.low); dp[3] = htonl (AUTH_NONE); dp[4] = htonl (0); return TRUE; } else return xdr_putint (x, AUTH_UINT) && xdr_putint (x, 4) && xdr_putint (x, auth->ah_key.key.low) && xdr_putint (x, AUTH_NONE) && xdr_putint (x, 0); }
/* For correctness, this must *NOT* return attributes (since we are * trying to defeat all kernel attribute and name caching). Note also * that the revocation/redirect mechanism also relies on readdirplus * not returning file handles or attributes. */ static bool xdr_putentryplus3 (XDR *x, afsnode *n, filename name, u_int32_t cookie) { return // entry * (non-null): xdr_putint (x, 1) // uint64 fileid: && xdr_puthyper (x, n->ino) // filename name: && xdr_filename (x, &name) // nfscookie cookie: && xdr_puthyper (x, cookie) // post_op_attr name_attributes; && xdr_putint (x, 0) // post_op_fh3 name_handle; && xdr_putint (x, 0); }
BOOL afsdir::xdr (XDR *x, void *_sbp) { /* When encoding . and .. in an XDR, we want to make sure the string * memory doesn't get freed before the XDR uses it. */ static const filename dot ("."); static const filename dotdot (".."); svccb *sbp = static_cast<svccb *> (_sbp); const sfs_aid aid = sbp2aid (sbp); assert (x->x_op == XDR_ENCODE); const bool v2 = sbp->vers () == 2; afsdir *d; u_int32_t cookie; u_int32_t count; bool (*putentry) (XDR *, afsnode *, filename, u_int32_t); if (v2) { const readdirargs *arg = sbp->Xtmpl getarg<readdirargs> (); d = static_cast<afsdir *> (afsnode::fh2node (&arg->dir)); cookie = getint (arg->cookie.base ()); count = arg->count; putentry = xdr_putentry; } else if (sbp->proc () == NFSPROC3_READDIR) { const readdir3args *arg = sbp->Xtmpl getarg<readdir3args> (); d = static_cast<afsdir *> (afsnode::fh3node (&arg->dir)); cookie = arg->cookie; count = arg->count; putentry = xdr_putentry3; } else if (sbp->proc () == NFSPROC3_READDIRPLUS) { const readdirplus3args *arg = sbp->Xtmpl getarg<readdirplus3args> (); d = static_cast<afsdir *> (afsnode::fh3node (&arg->dir)); cookie = arg->cookie; count = arg->dircount; putentry = xdr_putentryplus3; } else return xdr_putint (x, NFS3ERR_NOTSUPP); if (!d) return xdr_putint (x, NFSERR_STALE); afsdirentry *e = NULL; if (cookie >= 3 && (!(e = cookietab[cookie]) || !d->entryok (e, aid))) { warn ("afsdir::xdr: bad cookie 0x%x\n", cookie); return xdr_putint (x, v2 ? EINVAL : NFS3ERR_BAD_COOKIE); } if (!xdr_putint (x, NFS_OK)) return false; if (!v2) { post_op_attr poa; d->mkpoattr (poa, aid); if (!xdr_post_op_attr (x, &poa) || !xdr_puthyper (x, 0)) return false; } switch (cookie) { case 0: if (!putentry (x, d, dot, 1)) return false; case 1: if (!putentry (x, d->parent, dotdot, 2)) return false; case 2: e = d->firstentry (aid); break; default: e = d->nextentry (e, aid); break; } for (; e && XDR_GETPOS (x) + 24 + e->name.len () <= count; e = d->nextentry (e, aid)) if (!putentry (x, e->node, e->name, e->cookie)) return false; return xdr_putint (x, 0) // NULL entry * && xdr_putint (x, !e); // bool eof }