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  }