#![allow(dead_code)]
#![allow(non_camel_case_types)]
use crate::xdr::*;
use byteorder::{ReadBytesExt, WriteBytesExt};
use filetime;
use num_derive::{FromPrimitive, ToPrimitive};
use num_traits::cast::FromPrimitive;
use std::fmt;
use std::io::{Read, Write};
pub const PROGRAM: u32 = 100003;
pub const VERSION: u32 = 3;
pub const NFS3_FHSIZE: u32 = 64;
pub const NFS3_COOKIEVERFSIZE: u32 = 8;
pub const NFS3_CREATEVERFSIZE: u32 = 8;
pub const NFS3_WRITEVERFSIZE: u32 = 8;
#[allow(non_camel_case_types)]
#[derive(Default, Clone)]
pub struct nfsstring(pub Vec<u8>);
impl nfsstring {
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
impl From<Vec<u8>> for nfsstring {
fn from(value: Vec<u8>) -> Self {
Self(value)
}
}
impl From<&[u8]> for nfsstring {
fn from(value: &[u8]) -> Self {
Self(value.into())
}
}
impl AsRef<[u8]> for nfsstring {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
impl std::ops::Deref for nfsstring {
type Target = Vec<u8>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl fmt::Debug for nfsstring {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", String::from_utf8_lossy(&self.0))
}
}
impl fmt::Display for nfsstring {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", String::from_utf8_lossy(&self.0))
}
}
pub type opaque = u8;
pub type filename3 = nfsstring;
pub type nfspath3 = nfsstring;
pub type fileid3 = u64;
pub type cookie3 = u64;
pub type cookieverf3 = [opaque; NFS3_COOKIEVERFSIZE as usize];
pub type createverf3 = [opaque; NFS3_CREATEVERFSIZE as usize];
pub type writeverf3 = [opaque; NFS3_WRITEVERFSIZE as usize];
pub type uid3 = u32;
pub type gid3 = u32;
pub type size3 = u64;
pub type offset3 = u64;
pub type mode3 = u32;
pub type count3 = u32;
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug, FromPrimitive, ToPrimitive)]
#[repr(u32)]
pub enum nfsstat3 {
NFS3_OK = 0,
NFS3ERR_PERM = 1,
NFS3ERR_NOENT = 2,
NFS3ERR_IO = 5,
NFS3ERR_NXIO = 6,
NFS3ERR_ACCES = 13,
NFS3ERR_EXIST = 17,
NFS3ERR_XDEV = 18,
NFS3ERR_NODEV = 19,
NFS3ERR_NOTDIR = 20,
NFS3ERR_ISDIR = 21,
NFS3ERR_INVAL = 22,
NFS3ERR_FBIG = 27,
NFS3ERR_NOSPC = 28,
NFS3ERR_ROFS = 30,
NFS3ERR_MLINK = 31,
NFS3ERR_NAMETOOLONG = 63,
NFS3ERR_NOTEMPTY = 66,
NFS3ERR_DQUOT = 69,
NFS3ERR_STALE = 70,
NFS3ERR_REMOTE = 71,
NFS3ERR_BADHANDLE = 10001,
NFS3ERR_NOT_SYNC = 10002,
NFS3ERR_BAD_COOKIE = 10003,
NFS3ERR_NOTSUPP = 10004,
NFS3ERR_TOOSMALL = 10005,
NFS3ERR_SERVERFAULT = 10006,
NFS3ERR_BADTYPE = 10007,
NFS3ERR_JUKEBOX = 10008,
}
XDREnumSerde!(nfsstat3);
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug, Default, FromPrimitive, ToPrimitive)]
#[repr(u32)]
pub enum ftype3 {
#[default]
NF3REG = 1,
NF3DIR = 2,
NF3BLK = 3,
NF3CHR = 4,
NF3LNK = 5,
NF3SOCK = 6,
NF3FIFO = 7,
}
XDREnumSerde!(ftype3);
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug, Default)]
#[repr(C)]
pub struct specdata3 {
pub specdata1: u32,
pub specdata2: u32,
}
XDRStruct!(specdata3, specdata1, specdata2);
#[allow(non_camel_case_types)]
#[derive(Clone, Debug)]
pub struct nfs_fh3 {
pub data: Vec<u8>,
}
XDRStruct!(nfs_fh3, data);
#[allow(clippy::derivable_impls)]
impl Default for nfs_fh3 {
fn default() -> nfs_fh3 {
nfs_fh3 { data: Vec::new() }
}
}
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug, Default)]
#[repr(C)]
pub struct nfstime3 {
pub seconds: u32,
pub nseconds: u32,
}
XDRStruct!(nfstime3, seconds, nseconds);
impl From<nfstime3> for filetime::FileTime {
fn from(time: nfstime3) -> Self {
filetime::FileTime::from_unix_time(time.seconds as i64, time.nseconds)
}
}
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug, Default)]
pub struct fattr3 {
pub ftype: ftype3,
pub mode: mode3,
pub nlink: u32,
pub uid: uid3,
pub gid: gid3,
pub size: size3,
pub used: size3,
pub rdev: specdata3,
pub fsid: u64,
pub fileid: fileid3,
pub atime: nfstime3,
pub mtime: nfstime3,
pub ctime: nfstime3,
}
XDRStruct!(
fattr3, ftype, mode, nlink, uid, gid, size, used, rdev, fsid, fileid, atime, mtime, ctime
);
pub const FSF_LINK: u32 = 0x0001;
pub const FSF_SYMLINK: u32 = 0x0002;
pub const FSF_HOMOGENEOUS: u32 = 0x0008;
pub const FSF_CANSETTIME: u32 = 0x0010;
#[allow(non_camel_case_types)]
#[derive(Debug, Default)]
pub struct fsinfo3 {
pub obj_attributes: post_op_attr,
pub rtmax: u32,
pub rtpref: u32,
pub rtmult: u32,
pub wtmax: u32,
pub wtpref: u32,
pub wtmult: u32,
pub dtpref: u32,
pub maxfilesize: size3,
pub time_delta: nfstime3,
pub properties: u32,
}
XDRStruct!(
fsinfo3,
obj_attributes,
rtmax,
rtpref,
rtmult,
wtmax,
wtpref,
wtmult,
dtpref,
maxfilesize,
time_delta,
properties
);
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug, Default)]
pub struct wcc_attr {
pub size: size3,
pub mtime: nfstime3,
pub ctime: nfstime3,
}
XDRStruct!(wcc_attr, size, mtime, ctime);
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug, Default)]
#[repr(u32)]
pub enum pre_op_attr {
#[default]
Void,
attributes(wcc_attr),
}
XDRBoolUnion!(pre_op_attr, attributes, wcc_attr);
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug, Default)]
#[repr(u32)]
pub enum post_op_attr {
#[default]
Void,
attributes(fattr3),
}
XDRBoolUnion!(post_op_attr, attributes, fattr3);
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug, Default)]
pub struct wcc_data {
pub before: pre_op_attr,
pub after: post_op_attr,
}
XDRStruct!(wcc_data, before, after);
#[allow(non_camel_case_types)]
#[derive(Clone, Debug, Default)]
#[repr(u32)]
pub enum post_op_fh3 {
#[default]
Void,
handle(nfs_fh3),
}
XDRBoolUnion!(post_op_fh3, handle, nfs_fh3);
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug, FromPrimitive, ToPrimitive)]
#[repr(u32)]
pub enum _time_how {
DONT_CHANGE = 0,
SET_TO_SERVER_TIME = 1,
SET_TO_CLIENT_TIME = 2,
}
XDREnumSerde!(_time_how);
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum set_mode3 {
Void,
mode(mode3),
}
XDRBoolUnion!(set_mode3, mode, mode3);
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum set_uid3 {
Void,
uid(uid3),
}
XDRBoolUnion!(set_uid3, uid, uid3);
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum set_gid3 {
Void,
gid(gid3),
}
XDRBoolUnion!(set_gid3, gid, gid3);
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum set_size3 {
Void,
size(size3),
}
XDRBoolUnion!(set_size3, size, size3);
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum set_atime {
DONT_CHANGE,
SET_TO_SERVER_TIME,
SET_TO_CLIENT_TIME(nfstime3),
}
impl XDR for set_atime {
fn serialize<R: Write>(&self, dest: &mut R) -> std::io::Result<()> {
match self {
set_atime::DONT_CHANGE => {
0_u32.serialize(dest)?;
}
set_atime::SET_TO_SERVER_TIME => {
1_u32.serialize(dest)?;
}
set_atime::SET_TO_CLIENT_TIME(v) => {
2_u32.serialize(dest)?;
v.serialize(dest)?;
}
}
Ok(())
}
fn deserialize<R: Read>(&mut self, src: &mut R) -> std::io::Result<()> {
let mut c: u32 = 0;
c.deserialize(src)?;
if c == 0 {
*self = set_atime::DONT_CHANGE;
} else if c == 1 {
*self = set_atime::SET_TO_SERVER_TIME;
} else if c == 2 {
let mut r = nfstime3::default();
r.deserialize(src)?;
*self = set_atime::SET_TO_CLIENT_TIME(r);
} else {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"Invalid value for set_atime",
));
}
Ok(())
}
}
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum set_mtime {
DONT_CHANGE,
SET_TO_SERVER_TIME,
SET_TO_CLIENT_TIME(nfstime3),
}
impl XDR for set_mtime {
fn serialize<R: Write>(&self, dest: &mut R) -> std::io::Result<()> {
match self {
set_mtime::DONT_CHANGE => {
0_u32.serialize(dest)?;
}
set_mtime::SET_TO_SERVER_TIME => {
1_u32.serialize(dest)?;
}
set_mtime::SET_TO_CLIENT_TIME(v) => {
2_u32.serialize(dest)?;
v.serialize(dest)?;
}
}
Ok(())
}
fn deserialize<R: Read>(&mut self, src: &mut R) -> std::io::Result<()> {
let mut c: u32 = 0;
c.deserialize(src)?;
if c == 0 {
*self = set_mtime::DONT_CHANGE;
} else if c == 1 {
*self = set_mtime::SET_TO_SERVER_TIME;
} else if c == 2 {
let mut r = nfstime3::default();
r.deserialize(src)?;
*self = set_mtime::SET_TO_CLIENT_TIME(r);
} else {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"Invalid value for set_mtime",
));
}
Ok(())
}
}
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug)]
pub struct sattr3 {
pub mode: set_mode3,
pub uid: set_uid3,
pub gid: set_gid3,
pub size: set_size3,
pub atime: set_atime,
pub mtime: set_mtime,
}
XDRStruct!(sattr3, mode, uid, gid, size, atime, mtime);
impl Default for sattr3 {
fn default() -> sattr3 {
sattr3 {
mode: set_mode3::Void,
uid: set_uid3::Void,
gid: set_gid3::Void,
size: set_size3::Void,
atime: set_atime::DONT_CHANGE,
mtime: set_mtime::DONT_CHANGE,
}
}
}
#[allow(non_camel_case_types)]
#[derive(Clone, Debug, Default)]
pub struct diropargs3 {
pub dir: nfs_fh3,
pub name: filename3,
}
XDRStruct!(diropargs3, dir, name);
#[allow(non_camel_case_types)]
#[derive(Debug, Default)]
pub struct symlinkdata3 {
pub symlink_attributes: sattr3,
pub symlink_data: nfspath3,
}
XDRStruct!(symlinkdata3, symlink_attributes, symlink_data);
pub fn get_root_mount_handle() -> Vec<u8> {
vec![0]
}