diff --git a/packet.go b/packet.go index ac5abef..15845cb 100644 --- a/packet.go +++ b/packet.go @@ -2,7 +2,6 @@ package sftp import ( "encoding" - "encoding/hex" "fmt" "io" "reflect" @@ -103,7 +102,7 @@ func sendPacket(w io.Writer, m encoding.BinaryMarshaler) error { } l := uint32(len(bb)) hdr := []byte{byte(l >> 24), byte(l >> 16), byte(l >> 8), byte(l)} - debug("send packet %T, len: %v data: %v", m, l, hex.EncodeToString(bb)) + debug("send packet %T, len: %v", m, l) _, err = w.Write(hdr) if err != nil { return err @@ -128,7 +127,6 @@ func recvPacket(r io.Reader) (uint8, []byte, error) { debug("recv packet %d bytes: err %v", l, err) return 0, nil, err } - debug("recv packet %d bytes: %v", l, hex.EncodeToString(b)) return b[0], b[1:], nil } @@ -278,6 +276,10 @@ func (p sshFxpFstatPacket) MarshalBinary() ([]byte, error) { return marshalIdString(ssh_FXP_FSTAT, p.Id, p.Handle) } +func (p *sshFxpFstatPacket) UnmarshalBinary(b []byte) error { + return unmarshalIdString(b, &p.Id, &p.Handle) +} + type sshFxpClosePacket struct { Id uint32 Handle string diff --git a/server.go b/server.go index 08adc76..8101c50 100644 --- a/server.go +++ b/server.go @@ -154,6 +154,7 @@ func (svr *Server) decodePacket(pktType fxp, pktBytes []byte) (serverRespondable case ssh_FXP_WRITE: pkt = &sshFxpWritePacket{} case ssh_FXP_FSTAT: + pkt = &sshFxpFstatPacket{} case ssh_FXP_SETSTAT: case ssh_FXP_FSETSTAT: case ssh_FXP_OPENDIR: @@ -199,12 +200,12 @@ func (p sshFxInitPacket) respond(svr *Server) error { return svr.sendPacket(sshFxVersionPacket{sftpProtocolVersion, nil}) } -type sshFxpLstatReponse struct { +type sshFxpStatReponse struct { Id uint32 info os.FileInfo } -func (p sshFxpLstatReponse) MarshalBinary() ([]byte, error) { +func (p sshFxpStatReponse) MarshalBinary() ([]byte, error) { b := []byte{ssh_FXP_ATTRS} b = marshalUint32(b, p.Id) b = marshalFileInfo(b, p.info) @@ -216,7 +217,22 @@ func (p sshFxpLstatPacket) respond(svr *Server) error { if info, err := svr.fs.Lstat(p.Path); err != nil { return svr.sendPacket(statusFromError(p.Id, err)) } else { - return svr.sendPacket(sshFxpLstatReponse{p.Id, info}) + return svr.sendPacket(sshFxpStatReponse{p.Id, info}) + } +} + +func (p sshFxpFstatPacket) respond(svr *Server) error { + if f, ok := svr.getHandle(p.Handle); !ok { + return svr.sendPacket(statusFromError(p.Id, syscall.EBADF)) + } else if osf, ok := f.(*os.File); ok { + if info, err := osf.Stat(); err != nil { + return svr.sendPacket(statusFromError(p.Id, err)) + } else { + return svr.sendPacket(sshFxpStatReponse{p.Id, info}) + } + } else { + // server error... + return svr.sendPacket(statusFromError(p.Id, syscall.EBADF)) } }