/*
* Copyright (c) 2006-2009 Antti Kantee. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* buffering functions for network input/output. slightly different
* from the average joe buffer routines, as is usually the case ...
* these use efuns for now.
*/
if (va->va_size != (uint64_t)PUFFS_VNOVAL)
flags |= SSH_FILEXFER_ATTR_SIZE;
if (va->va_uid != (uid_t)PUFFS_VNOVAL) {
theuid = va->va_uid;
if (pctx->domangleuid && theuid == pctx->myuid)
theuid = pctx->mangleuid;
flags |= SSH_FILEXFER_ATTR_UIDGID;
}
if (va->va_gid != (gid_t)PUFFS_VNOVAL) {
thegid = va->va_gid;
if (pctx->domanglegid && thegid == pctx->mygid)
thegid = pctx->manglegid;
flags |= SSH_FILEXFER_ATTR_UIDGID;
}
if (va->va_mode != (mode_t)PUFFS_VNOVAL)
flags |= SSH_FILEXFER_ATTR_PERMISSIONS;
if (va->va_atime.tv_sec != PUFFS_VNOVAL)
flags |= SSH_FILEXFER_ATTR_ACCESSTIME;
psbuf_put_4(pb, flags);
if (flags & SSH_FILEXFER_ATTR_SIZE)
psbuf_put_8(pb, va->va_size);
if (flags & SSH_FILEXFER_ATTR_UIDGID) {
psbuf_put_4(pb, theuid);
psbuf_put_4(pb, thegid);
}
if (flags & SSH_FILEXFER_ATTR_PERMISSIONS)
psbuf_put_4(pb, va->va_mode);
/* XXX: this is totally wrong for protocol v3, see OpenSSH */
if (flags & SSH_FILEXFER_ATTR_ACCESSTIME) {
psbuf_put_4(pb, va->va_atime.tv_sec);
psbuf_put_4(pb, va->va_mtime.tv_sec);
}
}
if (flags & SSH_FILEXFER_ATTR_SIZE) {
FAILRV(psbuf_get_8(pb, &vap->va_size));
vap->va_bytes = vap->va_size;
}
if (flags & SSH_FILEXFER_ATTR_UIDGID) {
FAILRV(psbuf_get_4(pb, &vap->va_uid));
FAILRV(psbuf_get_4(pb, &vap->va_gid));
}
if (flags & SSH_FILEXFER_ATTR_PERMISSIONS) {
FAILRV(psbuf_get_4(pb, &vap->va_mode));
vap->va_type = puffs_mode2vt(vap->va_mode);
}
if (flags & SSH_FILEXFER_ATTR_ACCESSTIME) {
/*
* XXX: this is utterly wrong if we want to speak
* protocol version 3, but it seems like the
* "internet standard" for doing this
*/
FAILRV(psbuf_get_4(pb, &val));
vap->va_atime.tv_sec = val;
FAILRV(psbuf_get_4(pb, &val));
vap->va_mtime.tv_sec = val;
/* make ctime the same as mtime */
vap->va_ctime.tv_sec = val;