github.com/pkg/sftp@v1.13.6/internal/encoding/ssh/filexfer/openssh/hardlink.go (about) 1 package openssh 2 3 import ( 4 sshfx "github.com/pkg/sftp/internal/encoding/ssh/filexfer" 5 ) 6 7 const extensionHardlink = "hardlink@openssh.com" 8 9 // RegisterExtensionHardlink registers the "hardlink@openssh.com" extended packet with the encoding/ssh/filexfer package. 10 func RegisterExtensionHardlink() { 11 sshfx.RegisterExtendedPacketType(extensionHardlink, func() sshfx.ExtendedData { 12 return new(HardlinkExtendedPacket) 13 }) 14 } 15 16 // ExtensionHardlink returns an ExtensionPair suitable to append into an sshfx.InitPacket or sshfx.VersionPacket. 17 func ExtensionHardlink() *sshfx.ExtensionPair { 18 return &sshfx.ExtensionPair{ 19 Name: extensionHardlink, 20 Data: "1", 21 } 22 } 23 24 // HardlinkExtendedPacket defines the hardlink@openssh.com extend packet. 25 type HardlinkExtendedPacket struct { 26 OldPath string 27 NewPath string 28 } 29 30 // Type returns the SSH_FXP_EXTENDED packet type. 31 func (ep *HardlinkExtendedPacket) Type() sshfx.PacketType { 32 return sshfx.PacketTypeExtended 33 } 34 35 // MarshalPacket returns ep as a two-part binary encoding of the full extended packet. 36 func (ep *HardlinkExtendedPacket) MarshalPacket(reqid uint32, b []byte) (header, payload []byte, err error) { 37 p := &sshfx.ExtendedPacket{ 38 ExtendedRequest: extensionHardlink, 39 40 Data: ep, 41 } 42 return p.MarshalPacket(reqid, b) 43 } 44 45 // MarshalInto encodes ep into the binary encoding of the hardlink@openssh.com extended packet-specific data. 46 func (ep *HardlinkExtendedPacket) MarshalInto(buf *sshfx.Buffer) { 47 buf.AppendString(ep.OldPath) 48 buf.AppendString(ep.NewPath) 49 } 50 51 // MarshalBinary encodes ep into the binary encoding of the hardlink@openssh.com extended packet-specific data. 52 // 53 // NOTE: This _only_ encodes the packet-specific data, it does not encode the full extended packet. 54 func (ep *HardlinkExtendedPacket) MarshalBinary() ([]byte, error) { 55 // string(oldpath) + string(newpath) 56 size := 4 + len(ep.OldPath) + 4 + len(ep.NewPath) 57 58 buf := sshfx.NewBuffer(make([]byte, 0, size)) 59 ep.MarshalInto(buf) 60 return buf.Bytes(), nil 61 } 62 63 // UnmarshalFrom decodes the hardlink@openssh.com extended packet-specific data from buf. 64 func (ep *HardlinkExtendedPacket) UnmarshalFrom(buf *sshfx.Buffer) (err error) { 65 *ep = HardlinkExtendedPacket{ 66 OldPath: buf.ConsumeString(), 67 NewPath: buf.ConsumeString(), 68 } 69 70 return buf.Err 71 } 72 73 // UnmarshalBinary decodes the hardlink@openssh.com extended packet-specific data into ep. 74 func (ep *HardlinkExtendedPacket) UnmarshalBinary(data []byte) (err error) { 75 return ep.UnmarshalFrom(sshfx.NewBuffer(data)) 76 }