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 }