github.com/pkg/sftp@v1.13.6/internal/encoding/ssh/filexfer/openssh/statvfs.go (about)

     1  package openssh
     2  
     3  import (
     4  	sshfx "github.com/pkg/sftp/internal/encoding/ssh/filexfer"
     5  )
     6  
     7  const extensionStatVFS = "statvfs@openssh.com"
     8  
     9  // RegisterExtensionStatVFS registers the "statvfs@openssh.com" extended packet with the encoding/ssh/filexfer package.
    10  func RegisterExtensionStatVFS() {
    11  	sshfx.RegisterExtendedPacketType(extensionStatVFS, func() sshfx.ExtendedData {
    12  		return new(StatVFSExtendedPacket)
    13  	})
    14  }
    15  
    16  // ExtensionStatVFS returns an ExtensionPair suitable to append into an sshfx.InitPacket or sshfx.VersionPacket.
    17  func ExtensionStatVFS() *sshfx.ExtensionPair {
    18  	return &sshfx.ExtensionPair{
    19  		Name: extensionStatVFS,
    20  		Data: "2",
    21  	}
    22  }
    23  
    24  // StatVFSExtendedPacket defines the statvfs@openssh.com extend packet.
    25  type StatVFSExtendedPacket struct {
    26  	Path string
    27  }
    28  
    29  // Type returns the SSH_FXP_EXTENDED packet type.
    30  func (ep *StatVFSExtendedPacket) Type() sshfx.PacketType {
    31  	return sshfx.PacketTypeExtended
    32  }
    33  
    34  // MarshalPacket returns ep as a two-part binary encoding of the full extended packet.
    35  func (ep *StatVFSExtendedPacket) MarshalPacket(reqid uint32, b []byte) (header, payload []byte, err error) {
    36  	p := &sshfx.ExtendedPacket{
    37  		ExtendedRequest: extensionStatVFS,
    38  
    39  		Data: ep,
    40  	}
    41  	return p.MarshalPacket(reqid, b)
    42  }
    43  
    44  // MarshalInto encodes ep into the binary encoding of the statvfs@openssh.com extended packet-specific data.
    45  func (ep *StatVFSExtendedPacket) MarshalInto(buf *sshfx.Buffer) {
    46  	buf.AppendString(ep.Path)
    47  }
    48  
    49  // MarshalBinary encodes ep into the binary encoding of the statvfs@openssh.com extended packet-specific data.
    50  //
    51  // NOTE: This _only_ encodes the packet-specific data, it does not encode the full extended packet.
    52  func (ep *StatVFSExtendedPacket) MarshalBinary() ([]byte, error) {
    53  	size := 4 + len(ep.Path) // string(path)
    54  
    55  	buf := sshfx.NewBuffer(make([]byte, 0, size))
    56  
    57  	ep.MarshalInto(buf)
    58  
    59  	return buf.Bytes(), nil
    60  }
    61  
    62  // UnmarshalFrom decodes the statvfs@openssh.com extended packet-specific data into ep.
    63  func (ep *StatVFSExtendedPacket) UnmarshalFrom(buf *sshfx.Buffer) (err error) {
    64  	*ep = StatVFSExtendedPacket{
    65  		Path: buf.ConsumeString(),
    66  	}
    67  
    68  	return buf.Err
    69  }
    70  
    71  // UnmarshalBinary decodes the statvfs@openssh.com extended packet-specific data into ep.
    72  func (ep *StatVFSExtendedPacket) UnmarshalBinary(data []byte) (err error) {
    73  	return ep.UnmarshalFrom(sshfx.NewBuffer(data))
    74  }
    75  
    76  const extensionFStatVFS = "fstatvfs@openssh.com"
    77  
    78  // RegisterExtensionFStatVFS registers the "fstatvfs@openssh.com" extended packet with the encoding/ssh/filexfer package.
    79  func RegisterExtensionFStatVFS() {
    80  	sshfx.RegisterExtendedPacketType(extensionFStatVFS, func() sshfx.ExtendedData {
    81  		return new(FStatVFSExtendedPacket)
    82  	})
    83  }
    84  
    85  // ExtensionFStatVFS returns an ExtensionPair suitable to append into an sshfx.InitPacket or sshfx.VersionPacket.
    86  func ExtensionFStatVFS() *sshfx.ExtensionPair {
    87  	return &sshfx.ExtensionPair{
    88  		Name: extensionFStatVFS,
    89  		Data: "2",
    90  	}
    91  }
    92  
    93  // FStatVFSExtendedPacket defines the fstatvfs@openssh.com extend packet.
    94  type FStatVFSExtendedPacket struct {
    95  	Path string
    96  }
    97  
    98  // Type returns the SSH_FXP_EXTENDED packet type.
    99  func (ep *FStatVFSExtendedPacket) Type() sshfx.PacketType {
   100  	return sshfx.PacketTypeExtended
   101  }
   102  
   103  // MarshalPacket returns ep as a two-part binary encoding of the full extended packet.
   104  func (ep *FStatVFSExtendedPacket) MarshalPacket(reqid uint32, b []byte) (header, payload []byte, err error) {
   105  	p := &sshfx.ExtendedPacket{
   106  		ExtendedRequest: extensionFStatVFS,
   107  
   108  		Data: ep,
   109  	}
   110  	return p.MarshalPacket(reqid, b)
   111  }
   112  
   113  // MarshalInto encodes ep into the binary encoding of the statvfs@openssh.com extended packet-specific data.
   114  func (ep *FStatVFSExtendedPacket) MarshalInto(buf *sshfx.Buffer) {
   115  	buf.AppendString(ep.Path)
   116  }
   117  
   118  // MarshalBinary encodes ep into the binary encoding of the statvfs@openssh.com extended packet-specific data.
   119  //
   120  // NOTE: This _only_ encodes the packet-specific data, it does not encode the full extended packet.
   121  func (ep *FStatVFSExtendedPacket) MarshalBinary() ([]byte, error) {
   122  	size := 4 + len(ep.Path) // string(path)
   123  
   124  	buf := sshfx.NewBuffer(make([]byte, 0, size))
   125  
   126  	ep.MarshalInto(buf)
   127  
   128  	return buf.Bytes(), nil
   129  }
   130  
   131  // UnmarshalFrom decodes the statvfs@openssh.com extended packet-specific data into ep.
   132  func (ep *FStatVFSExtendedPacket) UnmarshalFrom(buf *sshfx.Buffer) (err error) {
   133  	*ep = FStatVFSExtendedPacket{
   134  		Path: buf.ConsumeString(),
   135  	}
   136  
   137  	return buf.Err
   138  }
   139  
   140  // UnmarshalBinary decodes the statvfs@openssh.com extended packet-specific data into ep.
   141  func (ep *FStatVFSExtendedPacket) UnmarshalBinary(data []byte) (err error) {
   142  	return ep.UnmarshalFrom(sshfx.NewBuffer(data))
   143  }
   144  
   145  // The values for the MountFlags field.
   146  // https://github.com/openssh/openssh-portable/blob/master/PROTOCOL
   147  const (
   148  	MountFlagsReadOnly = 0x1 // SSH_FXE_STATVFS_ST_RDONLY
   149  	MountFlagsNoSUID   = 0x2 // SSH_FXE_STATVFS_ST_NOSUID
   150  )
   151  
   152  // StatVFSExtendedReplyPacket defines the extended reply packet for statvfs@openssh.com and fstatvfs@openssh.com requests.
   153  type StatVFSExtendedReplyPacket struct {
   154  	BlockSize     uint64 /* f_bsize:   file system block size */
   155  	FragmentSize  uint64 /* f_frsize:  fundamental fs block size / fagment size */
   156  	Blocks        uint64 /* f_blocks:  number of blocks (unit f_frsize) */
   157  	BlocksFree    uint64 /* f_bfree:   free blocks in filesystem */
   158  	BlocksAvail   uint64 /* f_bavail:  free blocks for non-root */
   159  	Files         uint64 /* f_files:   total file inodes */
   160  	FilesFree     uint64 /* f_ffree:   free file inodes */
   161  	FilesAvail    uint64 /* f_favail:  free file inodes for to non-root */
   162  	FilesystemID  uint64 /* f_fsid:    file system id */
   163  	MountFlags    uint64 /* f_flag:    bit mask of mount flag values */
   164  	MaxNameLength uint64 /* f_namemax: maximum filename length */
   165  }
   166  
   167  // Type returns the SSH_FXP_EXTENDED_REPLY packet type.
   168  func (ep *StatVFSExtendedReplyPacket) Type() sshfx.PacketType {
   169  	return sshfx.PacketTypeExtendedReply
   170  }
   171  
   172  // MarshalPacket returns ep as a two-part binary encoding of the full extended reply packet.
   173  func (ep *StatVFSExtendedReplyPacket) MarshalPacket(reqid uint32, b []byte) (header, payload []byte, err error) {
   174  	p := &sshfx.ExtendedReplyPacket{
   175  		Data: ep,
   176  	}
   177  	return p.MarshalPacket(reqid, b)
   178  }
   179  
   180  // UnmarshalPacketBody returns ep as a two-part binary encoding of the full extended reply packet.
   181  func (ep *StatVFSExtendedReplyPacket) UnmarshalPacketBody(buf *sshfx.Buffer) (err error) {
   182  	p := &sshfx.ExtendedReplyPacket{
   183  		Data: ep,
   184  	}
   185  	return p.UnmarshalPacketBody(buf)
   186  }
   187  
   188  // MarshalInto encodes ep into the binary encoding of the (f)statvfs@openssh.com extended reply packet-specific data.
   189  func (ep *StatVFSExtendedReplyPacket) MarshalInto(buf *sshfx.Buffer) {
   190  	buf.AppendUint64(ep.BlockSize)
   191  	buf.AppendUint64(ep.FragmentSize)
   192  	buf.AppendUint64(ep.Blocks)
   193  	buf.AppendUint64(ep.BlocksFree)
   194  	buf.AppendUint64(ep.BlocksAvail)
   195  	buf.AppendUint64(ep.Files)
   196  	buf.AppendUint64(ep.FilesFree)
   197  	buf.AppendUint64(ep.FilesAvail)
   198  	buf.AppendUint64(ep.FilesystemID)
   199  	buf.AppendUint64(ep.MountFlags)
   200  	buf.AppendUint64(ep.MaxNameLength)
   201  }
   202  
   203  // MarshalBinary encodes ep into the binary encoding of the (f)statvfs@openssh.com extended reply packet-specific data.
   204  //
   205  // NOTE: This _only_ encodes the packet-specific data, it does not encode the full extended reply packet.
   206  func (ep *StatVFSExtendedReplyPacket) MarshalBinary() ([]byte, error) {
   207  	size := 11 * 8 // 11 × uint64(various)
   208  
   209  	b := sshfx.NewBuffer(make([]byte, 0, size))
   210  	ep.MarshalInto(b)
   211  	return b.Bytes(), nil
   212  }
   213  
   214  // UnmarshalFrom decodes the fstatvfs@openssh.com extended reply packet-specific data into ep.
   215  func (ep *StatVFSExtendedReplyPacket) UnmarshalFrom(buf *sshfx.Buffer) (err error) {
   216  	*ep = StatVFSExtendedReplyPacket{
   217  		BlockSize:     buf.ConsumeUint64(),
   218  		FragmentSize:  buf.ConsumeUint64(),
   219  		Blocks:        buf.ConsumeUint64(),
   220  		BlocksFree:    buf.ConsumeUint64(),
   221  		BlocksAvail:   buf.ConsumeUint64(),
   222  		Files:         buf.ConsumeUint64(),
   223  		FilesFree:     buf.ConsumeUint64(),
   224  		FilesAvail:    buf.ConsumeUint64(),
   225  		FilesystemID:  buf.ConsumeUint64(),
   226  		MountFlags:    buf.ConsumeUint64(),
   227  		MaxNameLength: buf.ConsumeUint64(),
   228  	}
   229  
   230  	return buf.Err
   231  }
   232  
   233  // UnmarshalBinary decodes the fstatvfs@openssh.com extended reply packet-specific data into ep.
   234  func (ep *StatVFSExtendedReplyPacket) UnmarshalBinary(data []byte) (err error) {
   235  	return ep.UnmarshalFrom(sshfx.NewBuffer(data))
   236  }