github.com/pkg/sftp@v1.13.6/packet-typing.go (about) 1 package sftp 2 3 import ( 4 "encoding" 5 "fmt" 6 ) 7 8 // all incoming packets 9 type requestPacket interface { 10 encoding.BinaryUnmarshaler 11 id() uint32 12 } 13 14 type responsePacket interface { 15 encoding.BinaryMarshaler 16 id() uint32 17 } 18 19 // interfaces to group types 20 type hasPath interface { 21 requestPacket 22 getPath() string 23 } 24 25 type hasHandle interface { 26 requestPacket 27 getHandle() string 28 } 29 30 type notReadOnly interface { 31 notReadOnly() 32 } 33 34 // // define types by adding methods 35 // hasPath 36 func (p *sshFxpLstatPacket) getPath() string { return p.Path } 37 func (p *sshFxpStatPacket) getPath() string { return p.Path } 38 func (p *sshFxpRmdirPacket) getPath() string { return p.Path } 39 func (p *sshFxpReadlinkPacket) getPath() string { return p.Path } 40 func (p *sshFxpRealpathPacket) getPath() string { return p.Path } 41 func (p *sshFxpMkdirPacket) getPath() string { return p.Path } 42 func (p *sshFxpSetstatPacket) getPath() string { return p.Path } 43 func (p *sshFxpStatvfsPacket) getPath() string { return p.Path } 44 func (p *sshFxpRemovePacket) getPath() string { return p.Filename } 45 func (p *sshFxpRenamePacket) getPath() string { return p.Oldpath } 46 func (p *sshFxpSymlinkPacket) getPath() string { return p.Targetpath } 47 func (p *sshFxpOpendirPacket) getPath() string { return p.Path } 48 func (p *sshFxpOpenPacket) getPath() string { return p.Path } 49 50 func (p *sshFxpExtendedPacketPosixRename) getPath() string { return p.Oldpath } 51 func (p *sshFxpExtendedPacketHardlink) getPath() string { return p.Oldpath } 52 53 // getHandle 54 func (p *sshFxpFstatPacket) getHandle() string { return p.Handle } 55 func (p *sshFxpFsetstatPacket) getHandle() string { return p.Handle } 56 func (p *sshFxpReadPacket) getHandle() string { return p.Handle } 57 func (p *sshFxpWritePacket) getHandle() string { return p.Handle } 58 func (p *sshFxpReaddirPacket) getHandle() string { return p.Handle } 59 func (p *sshFxpClosePacket) getHandle() string { return p.Handle } 60 61 // notReadOnly 62 func (p *sshFxpWritePacket) notReadOnly() {} 63 func (p *sshFxpSetstatPacket) notReadOnly() {} 64 func (p *sshFxpFsetstatPacket) notReadOnly() {} 65 func (p *sshFxpRemovePacket) notReadOnly() {} 66 func (p *sshFxpMkdirPacket) notReadOnly() {} 67 func (p *sshFxpRmdirPacket) notReadOnly() {} 68 func (p *sshFxpRenamePacket) notReadOnly() {} 69 func (p *sshFxpSymlinkPacket) notReadOnly() {} 70 func (p *sshFxpExtendedPacketPosixRename) notReadOnly() {} 71 func (p *sshFxpExtendedPacketHardlink) notReadOnly() {} 72 73 // some packets with ID are missing id() 74 func (p *sshFxpDataPacket) id() uint32 { return p.ID } 75 func (p *sshFxpStatusPacket) id() uint32 { return p.ID } 76 func (p *sshFxpStatResponse) id() uint32 { return p.ID } 77 func (p *sshFxpNamePacket) id() uint32 { return p.ID } 78 func (p *sshFxpHandlePacket) id() uint32 { return p.ID } 79 func (p *StatVFS) id() uint32 { return p.ID } 80 func (p *sshFxVersionPacket) id() uint32 { return 0 } 81 82 // take raw incoming packet data and build packet objects 83 func makePacket(p rxPacket) (requestPacket, error) { 84 var pkt requestPacket 85 switch p.pktType { 86 case sshFxpInit: 87 pkt = &sshFxInitPacket{} 88 case sshFxpLstat: 89 pkt = &sshFxpLstatPacket{} 90 case sshFxpOpen: 91 pkt = &sshFxpOpenPacket{} 92 case sshFxpClose: 93 pkt = &sshFxpClosePacket{} 94 case sshFxpRead: 95 pkt = &sshFxpReadPacket{} 96 case sshFxpWrite: 97 pkt = &sshFxpWritePacket{} 98 case sshFxpFstat: 99 pkt = &sshFxpFstatPacket{} 100 case sshFxpSetstat: 101 pkt = &sshFxpSetstatPacket{} 102 case sshFxpFsetstat: 103 pkt = &sshFxpFsetstatPacket{} 104 case sshFxpOpendir: 105 pkt = &sshFxpOpendirPacket{} 106 case sshFxpReaddir: 107 pkt = &sshFxpReaddirPacket{} 108 case sshFxpRemove: 109 pkt = &sshFxpRemovePacket{} 110 case sshFxpMkdir: 111 pkt = &sshFxpMkdirPacket{} 112 case sshFxpRmdir: 113 pkt = &sshFxpRmdirPacket{} 114 case sshFxpRealpath: 115 pkt = &sshFxpRealpathPacket{} 116 case sshFxpStat: 117 pkt = &sshFxpStatPacket{} 118 case sshFxpRename: 119 pkt = &sshFxpRenamePacket{} 120 case sshFxpReadlink: 121 pkt = &sshFxpReadlinkPacket{} 122 case sshFxpSymlink: 123 pkt = &sshFxpSymlinkPacket{} 124 case sshFxpExtended: 125 pkt = &sshFxpExtendedPacket{} 126 default: 127 return nil, fmt.Errorf("unhandled packet type: %s", p.pktType) 128 } 129 if err := pkt.UnmarshalBinary(p.pktBytes); err != nil { 130 // Return partially unpacked packet to allow callers to return 131 // error messages appropriately with necessary id() method. 132 return pkt, err 133 } 134 return pkt, nil 135 }