aboutsummaryrefslogtreecommitdiff
path: root/internal/encoding/ssh/filexfer/openssh/statvfs.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/encoding/ssh/filexfer/openssh/statvfs.go')
-rw-r--r--internal/encoding/ssh/filexfer/openssh/statvfs.go256
1 files changed, 256 insertions, 0 deletions
diff --git a/internal/encoding/ssh/filexfer/openssh/statvfs.go b/internal/encoding/ssh/filexfer/openssh/statvfs.go
new file mode 100644
index 0000000..3e9015f
--- /dev/null
+++ b/internal/encoding/ssh/filexfer/openssh/statvfs.go
@@ -0,0 +1,256 @@
+package openssh
+
+import (
+ sshfx "github.com/pkg/sftp/internal/encoding/ssh/filexfer"
+)
+
+const extensionStatVFS = "statvfs@openssh.com"
+
+// RegisterExtensionStatVFS registers the "statvfs@openssh.com" extended packet with the encoding/ssh/filexfer package.
+func RegisterExtensionStatVFS() {
+ sshfx.RegisterExtendedPacketType(extensionStatVFS, func() sshfx.ExtendedData {
+ return new(StatVFSExtendedPacket)
+ })
+}
+
+// ExtensionStatVFS returns an ExtensionPair suitable to append into an sshfx.InitPacket or sshfx.VersionPacket.
+func ExtensionStatVFS() *sshfx.ExtensionPair {
+ return &sshfx.ExtensionPair{
+ Name: extensionStatVFS,
+ Data: "2",
+ }
+}
+
+// StatVFSExtendedPacket defines the statvfs@openssh.com extend packet.
+type StatVFSExtendedPacket struct {
+ Path string
+}
+
+// Type returns the SSH_FXP_EXTENDED packet type.
+func (ep *StatVFSExtendedPacket) Type() sshfx.PacketType {
+ return sshfx.PacketTypeExtended
+}
+
+// MarshalPacket returns ep as a two-part binary encoding of the full extended packet.
+func (ep *StatVFSExtendedPacket) MarshalPacket(reqid uint32, b []byte) (header, payload []byte, err error) {
+ p := &sshfx.ExtendedPacket{
+ ExtendedRequest: extensionStatVFS,
+
+ Data: ep,
+ }
+ return p.MarshalPacket(reqid, b)
+}
+
+// MarshalInto encodes ep into the binary encoding of the statvfs@openssh.com extended packet-specific data.
+func (ep *StatVFSExtendedPacket) MarshalInto(buf *sshfx.Buffer) {
+ buf.AppendString(ep.Path)
+}
+
+// MarshalBinary encodes ep into the binary encoding of the statvfs@openssh.com extended packet-specific data.
+//
+// NOTE: This _only_ encodes the packet-specific data, it does not encode the full extended packet.
+func (ep *StatVFSExtendedPacket) MarshalBinary() ([]byte, error) {
+ size := 4 + len(ep.Path) // string(path)
+
+ buf := sshfx.NewBuffer(make([]byte, 0, size))
+
+ ep.MarshalInto(buf)
+
+ return buf.Bytes(), nil
+}
+
+// UnmarshalFrom decodes the statvfs@openssh.com extended packet-specific data into ep.
+func (ep *StatVFSExtendedPacket) UnmarshalFrom(buf *sshfx.Buffer) (err error) {
+ if ep.Path, err = buf.ConsumeString(); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// UnmarshalBinary decodes the statvfs@openssh.com extended packet-specific data into ep.
+func (ep *StatVFSExtendedPacket) UnmarshalBinary(data []byte) (err error) {
+ return ep.UnmarshalFrom(sshfx.NewBuffer(data))
+}
+
+const extensionFStatVFS = "fstatvfs@openssh.com"
+
+// RegisterExtensionFStatVFS registers the "fstatvfs@openssh.com" extended packet with the encoding/ssh/filexfer package.
+func RegisterExtensionFStatVFS() {
+ sshfx.RegisterExtendedPacketType(extensionFStatVFS, func() sshfx.ExtendedData {
+ return new(FStatVFSExtendedPacket)
+ })
+}
+
+// ExtensionFStatVFS returns an ExtensionPair suitable to append into an sshfx.InitPacket or sshfx.VersionPacket.
+func ExtensionFStatVFS() *sshfx.ExtensionPair {
+ return &sshfx.ExtensionPair{
+ Name: extensionFStatVFS,
+ Data: "2",
+ }
+}
+
+// FStatVFSExtendedPacket defines the fstatvfs@openssh.com extend packet.
+type FStatVFSExtendedPacket struct {
+ Path string
+}
+
+// Type returns the SSH_FXP_EXTENDED packet type.
+func (ep *FStatVFSExtendedPacket) Type() sshfx.PacketType {
+ return sshfx.PacketTypeExtended
+}
+
+// MarshalPacket returns ep as a two-part binary encoding of the full extended packet.
+func (ep *FStatVFSExtendedPacket) MarshalPacket(reqid uint32, b []byte) (header, payload []byte, err error) {
+ p := &sshfx.ExtendedPacket{
+ ExtendedRequest: extensionFStatVFS,
+
+ Data: ep,
+ }
+ return p.MarshalPacket(reqid, b)
+}
+
+// MarshalInto encodes ep into the binary encoding of the statvfs@openssh.com extended packet-specific data.
+func (ep *FStatVFSExtendedPacket) MarshalInto(buf *sshfx.Buffer) {
+ buf.AppendString(ep.Path)
+}
+
+// MarshalBinary encodes ep into the binary encoding of the statvfs@openssh.com extended packet-specific data.
+//
+// NOTE: This _only_ encodes the packet-specific data, it does not encode the full extended packet.
+func (ep *FStatVFSExtendedPacket) MarshalBinary() ([]byte, error) {
+ size := 4 + len(ep.Path) // string(path)
+
+ buf := sshfx.NewBuffer(make([]byte, 0, size))
+
+ ep.MarshalInto(buf)
+
+ return buf.Bytes(), nil
+}
+
+// UnmarshalFrom decodes the statvfs@openssh.com extended packet-specific data into ep.
+func (ep *FStatVFSExtendedPacket) UnmarshalFrom(buf *sshfx.Buffer) (err error) {
+ if ep.Path, err = buf.ConsumeString(); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// UnmarshalBinary decodes the statvfs@openssh.com extended packet-specific data into ep.
+func (ep *FStatVFSExtendedPacket) UnmarshalBinary(data []byte) (err error) {
+ return ep.UnmarshalFrom(sshfx.NewBuffer(data))
+}
+
+// The values for the MountFlags field.
+// https://github.com/openssh/openssh-portable/blob/master/PROTOCOL
+const (
+ MountFlagsReadOnly = 0x1 // SSH_FXE_STATVFS_ST_RDONLY
+ MountFlagsNoSUID = 0x2 // SSH_FXE_STATVFS_ST_NOSUID
+)
+
+// StatVFSExtendedReplyPacket defines the extended reply packet for statvfs@openssh.com and fstatvfs@openssh.com requests.
+type StatVFSExtendedReplyPacket struct {
+ BlockSize uint64 /* f_bsize: file system block size */
+ FragmentSize uint64 /* f_frsize: fundamental fs block size / fagment size */
+ Blocks uint64 /* f_blocks: number of blocks (unit f_frsize) */
+ BlocksFree uint64 /* f_bfree: free blocks in filesystem */
+ BlocksAvail uint64 /* f_bavail: free blocks for non-root */
+ Files uint64 /* f_files: total file inodes */
+ FilesFree uint64 /* f_ffree: free file inodes */
+ FilesAvail uint64 /* f_favail: free file inodes for to non-root */
+ FilesystemID uint64 /* f_fsid: file system id */
+ MountFlags uint64 /* f_flag: bit mask of mount flag values */
+ MaxNameLength uint64 /* f_namemax: maximum filename length */
+}
+
+// Type returns the SSH_FXP_EXTENDED_REPLY packet type.
+func (ep *StatVFSExtendedReplyPacket) Type() sshfx.PacketType {
+ return sshfx.PacketTypeExtendedReply
+}
+
+// MarshalPacket returns ep as a two-part binary encoding of the full extended reply packet.
+func (ep *StatVFSExtendedReplyPacket) MarshalPacket(reqid uint32, b []byte) (header, payload []byte, err error) {
+ p := &sshfx.ExtendedReplyPacket{
+ Data: ep,
+ }
+ return p.MarshalPacket(reqid, b)
+}
+
+// UnmarshalPacketBody returns ep as a two-part binary encoding of the full extended reply packet.
+func (ep *StatVFSExtendedReplyPacket) UnmarshalPacketBody(buf *sshfx.Buffer) (err error) {
+ p := &sshfx.ExtendedReplyPacket{
+ Data: ep,
+ }
+ return p.UnmarshalPacketBody(buf)
+}
+
+// MarshalInto encodes ep into the binary encoding of the (f)statvfs@openssh.com extended reply packet-specific data.
+func (ep *StatVFSExtendedReplyPacket) MarshalInto(buf *sshfx.Buffer) {
+ buf.AppendUint64(ep.BlockSize)
+ buf.AppendUint64(ep.FragmentSize)
+ buf.AppendUint64(ep.Blocks)
+ buf.AppendUint64(ep.BlocksFree)
+ buf.AppendUint64(ep.BlocksAvail)
+ buf.AppendUint64(ep.Files)
+ buf.AppendUint64(ep.FilesFree)
+ buf.AppendUint64(ep.FilesAvail)
+ buf.AppendUint64(ep.FilesystemID)
+ buf.AppendUint64(ep.MountFlags)
+ buf.AppendUint64(ep.MaxNameLength)
+}
+
+// MarshalBinary encodes ep into the binary encoding of the (f)statvfs@openssh.com extended reply packet-specific data.
+//
+// NOTE: This _only_ encodes the packet-specific data, it does not encode the full extended reply packet.
+func (ep *StatVFSExtendedReplyPacket) MarshalBinary() ([]byte, error) {
+ size := 11 * 8 // 11 × uint64(various)
+
+ b := sshfx.NewBuffer(make([]byte, 0, size))
+ ep.MarshalInto(b)
+ return b.Bytes(), nil
+}
+
+// UnmarshalFrom decodes the fstatvfs@openssh.com extended reply packet-specific data into ep.
+func (ep *StatVFSExtendedReplyPacket) UnmarshalFrom(buf *sshfx.Buffer) (err error) {
+ if ep.BlockSize, err = buf.ConsumeUint64(); err != nil {
+ return err
+ }
+ if ep.FragmentSize, err = buf.ConsumeUint64(); err != nil {
+ return err
+ }
+ if ep.Blocks, err = buf.ConsumeUint64(); err != nil {
+ return err
+ }
+ if ep.BlocksFree, err = buf.ConsumeUint64(); err != nil {
+ return err
+ }
+ if ep.BlocksAvail, err = buf.ConsumeUint64(); err != nil {
+ return err
+ }
+ if ep.Files, err = buf.ConsumeUint64(); err != nil {
+ return err
+ }
+ if ep.FilesFree, err = buf.ConsumeUint64(); err != nil {
+ return err
+ }
+ if ep.FilesAvail, err = buf.ConsumeUint64(); err != nil {
+ return err
+ }
+ if ep.FilesystemID, err = buf.ConsumeUint64(); err != nil {
+ return err
+ }
+ if ep.MountFlags, err = buf.ConsumeUint64(); err != nil {
+ return err
+ }
+ if ep.MaxNameLength, err = buf.ConsumeUint64(); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// UnmarshalBinary decodes the fstatvfs@openssh.com extended reply packet-specific data into ep.
+func (ep *StatVFSExtendedReplyPacket) UnmarshalBinary(data []byte) (err error) {
+ return ep.UnmarshalFrom(sshfx.NewBuffer(data))
+}