void sftp_v456_sendattrs(struct sftpjob *job, const struct sftpattr *attrs) { const uint32_t valid = attrs->valid & protocol->attrmask; sftp_send_uint32(job->worker, valid); sftp_send_uint8(job->worker, attrs->type); if(valid & SSH_FILEXFER_ATTR_SIZE) sftp_send_uint64(job->worker, attrs->size); if(valid & SSH_FILEXFER_ATTR_OWNERGROUP) { sftp_send_path(job, job->worker, attrs->owner); sftp_send_path(job, job->worker, attrs->group); } if(valid & SSH_FILEXFER_ATTR_PERMISSIONS) sftp_send_uint32(job->worker, attrs->permissions); /* lftp 3.1.3 expects subsecond time fields even if the corresonding time is * absent. It sends no identifying information so we cannot enable a * workaround for this bizarre bug. lftp 3.5.9 gets this right as does * WinSCP. */ if(valid & SSH_FILEXFER_ATTR_ACCESSTIME) { sftp_send_uint64(job->worker, attrs->atime.seconds); if(valid & SSH_FILEXFER_ATTR_SUBSECOND_TIMES) sftp_send_uint32(job->worker, attrs->atime.nanoseconds); } if(valid & SSH_FILEXFER_ATTR_CREATETIME) { sftp_send_uint64(job->worker, attrs->createtime.seconds); if(valid & SSH_FILEXFER_ATTR_SUBSECOND_TIMES) sftp_send_uint32(job->worker, attrs->createtime.nanoseconds); } if(valid & SSH_FILEXFER_ATTR_MODIFYTIME) { sftp_send_uint64(job->worker, attrs->mtime.seconds); if(valid & SSH_FILEXFER_ATTR_SUBSECOND_TIMES) sftp_send_uint32(job->worker, attrs->mtime.nanoseconds); } if(valid & SSH_FILEXFER_ATTR_CTIME) { sftp_send_uint64(job->worker, attrs->ctime.seconds); if(valid & SSH_FILEXFER_ATTR_SUBSECOND_TIMES) sftp_send_uint32(job->worker, attrs->ctime.nanoseconds); } if(valid & SSH_FILEXFER_ATTR_ACL) { sftp_send_string(job->worker, attrs->acl); } if(valid & SSH_FILEXFER_ATTR_BITS) { sftp_send_uint32(job->worker, attrs->attrib_bits); if(protocol->version >= 6) sftp_send_uint32(job->worker, attrs->attrib_bits_valid); } if(valid & SSH_FILEXFER_ATTR_TEXT_HINT) { sftp_send_uint8(job->worker, attrs->text_hint); } if(valid & SSH_FILEXFER_ATTR_MIME_TYPE) { sftp_send_string(job->worker, attrs->mime_type); } if(valid & SSH_FILEXFER_ATTR_LINK_COUNT) { sftp_send_uint32(job->worker, attrs->link_count); } /* We don't implement untranslated-name yet */ }
void sftp_send_path(struct sftpjob *job, struct worker *w, const char *path) { if(protocol->encode(job, (char **)&path)) fatal("cannot encode local path name '%s'", path); sftp_send_string(w, path); }