implement write

This commit is contained in:
Mark Sheahan 2015-07-29 17:37:58 -07:00
parent 2888b4a6b1
commit c9cee8ac6f
2 changed files with 44 additions and 10 deletions

View File

@ -429,6 +429,24 @@ func (s sshFxpWritePacket) MarshalBinary() ([]byte, error) {
return b, nil
}
func (p *sshFxpWritePacket) UnmarshalBinary(b []byte) (err error) {
if p.Id, b, err = unmarshalUint32Safe(b); err != nil {
return
} else if p.Handle, b, err = unmarshalStringSafe(b); err != nil {
return
} else if p.Offset, b, err = unmarshalUint64Safe(b); err != nil {
return
} else if p.Length, b, err = unmarshalUint32Safe(b); err != nil {
return
} else if uint32(len(b)) < p.Length {
err = shortPacketError
return
} else {
p.Data = append([]byte{}, b[:p.Length]...)
}
return
}
type sshFxpMkdirPacket struct {
Id uint32
Path string

View File

@ -152,6 +152,7 @@ func (svr *Server) decodePacket(pktType fxp, pktBytes []byte) (serverRespondable
case ssh_FXP_READ:
pkt = &sshFxpReadPacket{}
case ssh_FXP_WRITE:
pkt = &sshFxpWritePacket{}
case ssh_FXP_FSTAT:
case ssh_FXP_SETSTAT:
case ssh_FXP_FSETSTAT:
@ -273,17 +274,32 @@ func (p sshFxpClosePacket) respond(svr *Server) error {
func (p sshFxpReadPacket) respond(svr *Server) error {
if f, ok := svr.getHandle(p.Handle); !ok {
return svr.sendPacket(statusFromError(p.Id, syscall.EBADF))
} else if p.Len > maxWritePacket {
return svr.sendPacket(statusFromError(p.Id, syscall.EINVAL))
} else if osf, ok := f.(*os.File); ok {
debug("in readpacket server respond: len %d", p.Len)
ret := sshFxpDataPacket{Id: p.Id, Length: p.Len, Data: make([]byte, p.Len)}
if n, err := osf.ReadAt(ret.Data, int64(p.Offset)); err != nil && (err != io.EOF || n == 0) {
return svr.sendPacket(statusFromError(p.Id, err))
} else {
ret.Length = uint32(n)
return svr.sendPacket(ret)
} else {
if p.Len > maxWritePacket {
p.Len = maxWritePacket
}
if osf, ok := f.(*os.File); ok {
debug("in readpacket server respond: len %d", p.Len)
ret := sshFxpDataPacket{Id: p.Id, Length: p.Len, Data: make([]byte, p.Len)}
if n, err := osf.ReadAt(ret.Data, int64(p.Offset)); err != nil && (err != io.EOF || n == 0) {
return svr.sendPacket(statusFromError(p.Id, err))
} else {
ret.Length = uint32(n)
return svr.sendPacket(ret)
}
} else {
// server error...
return svr.sendPacket(statusFromError(p.Id, syscall.EBADF))
}
}
}
func (p sshFxpWritePacket) 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 {
_, err := osf.WriteAt(p.Data, int64(p.Offset))
return svr.sendPacket(statusFromError(p.Id, err))
} else {
// server error...
return svr.sendPacket(statusFromError(p.Id, syscall.EBADF))