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  }