github.com/pkg/sftp@v1.13.6/internal/encoding/ssh/filexfer/handle_packets.go (about) 1 package sshfx 2 3 // ClosePacket defines the SSH_FXP_CLOSE packet. 4 type ClosePacket struct { 5 Handle string 6 } 7 8 // Type returns the SSH_FXP_xy value associated with this packet type. 9 func (p *ClosePacket) Type() PacketType { 10 return PacketTypeClose 11 } 12 13 // MarshalPacket returns p as a two-part binary encoding of p. 14 func (p *ClosePacket) MarshalPacket(reqid uint32, b []byte) (header, payload []byte, err error) { 15 buf := NewBuffer(b) 16 if buf.Cap() < 9 { 17 size := 4 + len(p.Handle) // string(handle) 18 buf = NewMarshalBuffer(size) 19 } 20 21 buf.StartPacket(PacketTypeClose, reqid) 22 buf.AppendString(p.Handle) 23 24 return buf.Packet(payload) 25 } 26 27 // UnmarshalPacketBody unmarshals the packet body from the given Buffer. 28 // It is assumed that the uint32(request-id) has already been consumed. 29 func (p *ClosePacket) UnmarshalPacketBody(buf *Buffer) (err error) { 30 *p = ClosePacket{ 31 Handle: buf.ConsumeString(), 32 } 33 34 return buf.Err 35 } 36 37 // ReadPacket defines the SSH_FXP_READ packet. 38 type ReadPacket struct { 39 Handle string 40 Offset uint64 41 Length uint32 42 } 43 44 // Type returns the SSH_FXP_xy value associated with this packet type. 45 func (p *ReadPacket) Type() PacketType { 46 return PacketTypeRead 47 } 48 49 // MarshalPacket returns p as a two-part binary encoding of p. 50 func (p *ReadPacket) MarshalPacket(reqid uint32, b []byte) (header, payload []byte, err error) { 51 buf := NewBuffer(b) 52 if buf.Cap() < 9 { 53 // string(handle) + uint64(offset) + uint32(len) 54 size := 4 + len(p.Handle) + 8 + 4 55 buf = NewMarshalBuffer(size) 56 } 57 58 buf.StartPacket(PacketTypeRead, reqid) 59 buf.AppendString(p.Handle) 60 buf.AppendUint64(p.Offset) 61 buf.AppendUint32(p.Length) 62 63 return buf.Packet(payload) 64 } 65 66 // UnmarshalPacketBody unmarshals the packet body from the given Buffer. 67 // It is assumed that the uint32(request-id) has already been consumed. 68 func (p *ReadPacket) UnmarshalPacketBody(buf *Buffer) (err error) { 69 *p = ReadPacket{ 70 Handle: buf.ConsumeString(), 71 Offset: buf.ConsumeUint64(), 72 Length: buf.ConsumeUint32(), 73 } 74 75 return buf.Err 76 } 77 78 // WritePacket defines the SSH_FXP_WRITE packet. 79 type WritePacket struct { 80 Handle string 81 Offset uint64 82 Data []byte 83 } 84 85 // Type returns the SSH_FXP_xy value associated with this packet type. 86 func (p *WritePacket) Type() PacketType { 87 return PacketTypeWrite 88 } 89 90 // MarshalPacket returns p as a two-part binary encoding of p. 91 func (p *WritePacket) MarshalPacket(reqid uint32, b []byte) (header, payload []byte, err error) { 92 buf := NewBuffer(b) 93 if buf.Cap() < 9 { 94 // string(handle) + uint64(offset) + uint32(len(data)); data content in payload 95 size := 4 + len(p.Handle) + 8 + 4 96 buf = NewMarshalBuffer(size) 97 } 98 99 buf.StartPacket(PacketTypeWrite, reqid) 100 buf.AppendString(p.Handle) 101 buf.AppendUint64(p.Offset) 102 buf.AppendUint32(uint32(len(p.Data))) 103 104 return buf.Packet(p.Data) 105 } 106 107 // UnmarshalPacketBody unmarshals the packet body from the given Buffer. 108 // It is assumed that the uint32(request-id) has already been consumed. 109 // 110 // If p.Data is already populated, and of sufficient length to hold the data, 111 // then this will copy the data into that byte slice. 112 // 113 // If p.Data has a length insufficient to hold the data, 114 // then this will make a new slice of sufficient length, and copy the data into that. 115 // 116 // This means this _does not_ alias any of the data buffer that is passed in. 117 func (p *WritePacket) UnmarshalPacketBody(buf *Buffer) (err error) { 118 *p = WritePacket{ 119 Handle: buf.ConsumeString(), 120 Offset: buf.ConsumeUint64(), 121 Data: buf.ConsumeByteSliceCopy(p.Data), 122 } 123 124 return buf.Err 125 } 126 127 // FStatPacket defines the SSH_FXP_FSTAT packet. 128 type FStatPacket struct { 129 Handle string 130 } 131 132 // Type returns the SSH_FXP_xy value associated with this packet type. 133 func (p *FStatPacket) Type() PacketType { 134 return PacketTypeFStat 135 } 136 137 // MarshalPacket returns p as a two-part binary encoding of p. 138 func (p *FStatPacket) MarshalPacket(reqid uint32, b []byte) (header, payload []byte, err error) { 139 buf := NewBuffer(b) 140 if buf.Cap() < 9 { 141 size := 4 + len(p.Handle) // string(handle) 142 buf = NewMarshalBuffer(size) 143 } 144 145 buf.StartPacket(PacketTypeFStat, reqid) 146 buf.AppendString(p.Handle) 147 148 return buf.Packet(payload) 149 } 150 151 // UnmarshalPacketBody unmarshals the packet body from the given Buffer. 152 // It is assumed that the uint32(request-id) has already been consumed. 153 func (p *FStatPacket) UnmarshalPacketBody(buf *Buffer) (err error) { 154 *p = FStatPacket{ 155 Handle: buf.ConsumeString(), 156 } 157 158 return buf.Err 159 } 160 161 // FSetstatPacket defines the SSH_FXP_FSETSTAT packet. 162 type FSetstatPacket struct { 163 Handle string 164 Attrs Attributes 165 } 166 167 // Type returns the SSH_FXP_xy value associated with this packet type. 168 func (p *FSetstatPacket) Type() PacketType { 169 return PacketTypeFSetstat 170 } 171 172 // MarshalPacket returns p as a two-part binary encoding of p. 173 func (p *FSetstatPacket) MarshalPacket(reqid uint32, b []byte) (header, payload []byte, err error) { 174 buf := NewBuffer(b) 175 if buf.Cap() < 9 { 176 size := 4 + len(p.Handle) + p.Attrs.Len() // string(handle) + ATTRS(attrs) 177 buf = NewMarshalBuffer(size) 178 } 179 180 buf.StartPacket(PacketTypeFSetstat, reqid) 181 buf.AppendString(p.Handle) 182 183 p.Attrs.MarshalInto(buf) 184 185 return buf.Packet(payload) 186 } 187 188 // UnmarshalPacketBody unmarshals the packet body from the given Buffer. 189 // It is assumed that the uint32(request-id) has already been consumed. 190 func (p *FSetstatPacket) UnmarshalPacketBody(buf *Buffer) (err error) { 191 *p = FSetstatPacket{ 192 Handle: buf.ConsumeString(), 193 } 194 195 return p.Attrs.UnmarshalFrom(buf) 196 } 197 198 // ReadDirPacket defines the SSH_FXP_READDIR packet. 199 type ReadDirPacket struct { 200 Handle string 201 } 202 203 // Type returns the SSH_FXP_xy value associated with this packet type. 204 func (p *ReadDirPacket) Type() PacketType { 205 return PacketTypeReadDir 206 } 207 208 // MarshalPacket returns p as a two-part binary encoding of p. 209 func (p *ReadDirPacket) MarshalPacket(reqid uint32, b []byte) (header, payload []byte, err error) { 210 buf := NewBuffer(b) 211 if buf.Cap() < 9 { 212 size := 4 + len(p.Handle) // string(handle) 213 buf = NewMarshalBuffer(size) 214 } 215 216 buf.StartPacket(PacketTypeReadDir, reqid) 217 buf.AppendString(p.Handle) 218 219 return buf.Packet(payload) 220 } 221 222 // UnmarshalPacketBody unmarshals the packet body from the given Buffer. 223 // It is assumed that the uint32(request-id) has already been consumed. 224 func (p *ReadDirPacket) UnmarshalPacketBody(buf *Buffer) (err error) { 225 *p = ReadDirPacket{ 226 Handle: buf.ConsumeString(), 227 } 228 229 return buf.Err 230 }