├── .gitignore ├── HISTORY.md ├── LICENSE ├── README.rst ├── pyNfsClient ├── __info__.py ├── __init__.py ├── const.py ├── mount.py ├── nfs3.py ├── pack.py ├── portmap.py ├── rpc.py ├── rtypes.py └── utils.py ├── setup.cfg └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | -------------------------------------------------------------------------------- /HISTORY.md: -------------------------------------------------------------------------------- 1 | Release History 2 | =============== 3 | 4 | dev 5 | --- 6 | 7 | **Bugfixes** 8 | 9 | - \[Short description of non-trivial change.\] 10 | 11 | 0.1.5 (2019-06-04) 12 | ------------------ 13 | 14 | - Solve reference error on xdrlib 15 | 16 | 0.1 (2019-04-08) 17 | ------------------ 18 | 19 | - Initial version 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Cooper Yang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | pyNfsClient 2 | =============== 3 | 4 | .. contents:: 5 | :local: 6 | 7 | Introduction 8 | ------------ 9 | 10 | pyNfsClient is a generic open source toolkit for Linux NFS file system simulation as client. 11 | Constructed parameters sent via RPC and then analyse the response in reference to NFS protocol specifications (RFC1813). 12 | You could form your custom scenarios that consist of basic actions to meet expecations. 13 | **Currently only NFS v3 supported, NFS v4.1 is under development.** 14 | 15 | pyNfsClient is operating system and application independent. The toolkit is implemented using 16 | `Python `__, supports both 17 | Python 2.7 and Python 3. 18 | 19 | pyNfsClient project is hosted on GitHub_ where you can find source code, 20 | an issue tracker, and some further documentation. 21 | 22 | .. _GitHub: https://github.com/CharmingYang0/NfsClient 23 | .. _PyPI: https://pypi.org/project/pyNfsClient 24 | 25 | .. image:: https://img.shields.io/pypi/v/pyNfsClient.svg?label=version 26 | :target: https://pypi.org/project/pyNfsClient/ 27 | :alt: Latest version 28 | 29 | Installation 30 | ------------ 31 | 32 | If you already have `Python `__ with `pip `__ installed, 33 | you can simply run:: 34 | 35 | pip install pyNfsClient 36 | 37 | Alternatively you can get source code by downloading the source 38 | distribution from PyPI_ and extracting it, or by cloning the project repository 39 | from GitHub_. After that you can install the framework with:: 40 | 41 | python setup.py install 42 | 43 | Example 44 | ------- 45 | 46 | Below is a simple example which lookup a file and then do several operations on it. 47 | 48 | .. code:: python 49 | 50 | from pyNfsClient import (Portmap, Mount, NFSv3, MNT3_OK, NFS_PROGRAM, 51 | NFS_V3, NFS3_OK, DATA_SYNC) 52 | 53 | # variable preparation 54 | host = "192.221.4.119" 55 | mount_path = "/nfsshare" 56 | 57 | auth = {"flavor": 1, 58 | "machine_name": "host1", 59 | "uid": 0, 60 | "gid": 0, 61 | "aux_gid": list(), 62 | } 63 | 64 | # portmap initialization 65 | portmap = Portmap(host, timeout=3600) 66 | portmap.connect() 67 | 68 | # mount initialization 69 | mnt_port = portmap.getport(Mount.program, Mount.program_version) 70 | mount = Mount(host=host, port=mnt_port, timeout=3600) 71 | mount.connect() 72 | 73 | # do mount 74 | mnt_res =mount.mnt(mount_path, auth) 75 | if mnt_res["status"] == MNT3_OK: 76 | root_fh =mnt_res["mountinfo"]["fhandle"] 77 | try: 78 | nfs_port =portmap.getport(NFS_PROGRAM, NFS_V3) 79 | # nfs actions 80 | nfs3 =NFSv3(host, nfs_port, 3600) 81 | nfs3.connect() 82 | lookup_res = nfs3.lookup(root_fh, "file.txt", auth) 83 | if lookup_res["status"] == NFS3_OK: 84 | fh = lookup_res["resok"]["object"]["data"] 85 | write_res = nfs3.write(fh, offset=0, count=11, content="Sample text", 86 | stable_how=DATA_SYNC, auth=auth) 87 | if write_res["status"] == NFS3_OK: 88 | read_res = nfs3.read(fh, offset=0, auth=auth) 89 | if read_res["status"] == NFS3_OK: 90 | read_content = str(read_res["resok"]["data"], encoding="utf-8") 91 | assert read_content.startswith("Sample text") 92 | else: 93 | print("write failed") 94 | else: 95 | print("Lookup failed") 96 | finally: 97 | if nfs3: 98 | nfs3.disconnect() 99 | mount.umnt(mount_path, auth) 100 | mount.disconnect() 101 | portmap.disconnect() 102 | else: 103 | mount.disconnect() 104 | portmap.disconnect() 105 | 106 | License 107 | ------- 108 | 109 | **The MIT License (MIT)** 110 | 111 | Copyright (c) 2019 `Cooper Yang `__ 112 | 113 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 114 | 115 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 116 | 117 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 118 | -------------------------------------------------------------------------------- /pyNfsClient/__info__.py: -------------------------------------------------------------------------------- 1 | __title__ = "pyNfsClient" 2 | __description__ = "Pure python NFS client" 3 | __version__ = "0.1.5" 4 | __license__ = "MIT" 5 | __url__ = "https://github.com/CharmingYang0/NfsClient" 6 | __author__ = "Cooper Yang" 7 | __author_email__ = "cm_yang@yeah.net" 8 | -------------------------------------------------------------------------------- /pyNfsClient/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | import logging 3 | from logging import NullHandler 4 | from .__info__ import (__version__, __author__, __author_email__, __description__) 5 | from .rpc import RPC 6 | from .portmap import Portmap 7 | from .mount import Mount 8 | from .nfs3 import NFSv3 9 | from .const import * 10 | 11 | logging.getLogger(__package__).addHandler(NullHandler()) 12 | 13 | __author__ = "{} <{}>".format(__author__, __author_email__) 14 | __version__ = __version__ 15 | __doc__ = __description__ 16 | 17 | 18 | def release_all_rpc(): 19 | RPC.disconnect_all() 20 | 21 | 22 | __all__ = ("Portmap", "Mount", "NFSv3", "MOUNT_PROGRAM", "MNT3_OK", "MNT3ERR_ACCES", "MNT3ERR_INVAL", "MNT3ERR_IO", 23 | "MNT3ERR_NAMETOOLONG", "MNT3ERR_NOENT", "MNT3ERR_NOTDIR", "MNT3ERR_NOTSUPP", "MNT3ERR_PERM", 24 | "MNT3ERR_SERVERFAULT", "MOUNTSTAT3", "NFSSTAT3", "NFS3_OK", "NFS3ERR_ACCES", "NFS3ERR_BAD_COOKIE", 25 | "NFS3ERR_BADHANDLE", "NFS3ERR_BADTYPE", "NFS3ERR_DQUOT", "NFS3ERR_EXIST", "NFS3ERR_FBIG", 26 | "NFS3ERR_INVAL", "NFS3ERR_IO", "NFS3ERR_ISDIR", "NFS3ERR_JUKEBOX", "NFS3ERR_MLINK", "NFS3ERR_NXIO", 27 | "NFS3ERR_NAMETOOLONG", "NFS3ERR_NODEV", "NFS3ERR_NOENT", "NFS3ERR_NOSPC", "NFS3ERR_NOTDIR", 28 | "NFS3ERR_NOT_SYNC", "NFS3ERR_NOTEMPTY", "NFS3ERR_NOTSUPP", "NFS3ERR_PERM", "NFS3ERR_REMOTE", 29 | "NFS3ERR_ROFS", "NFS3ERR_SERVERFAULT", "NFS3ERR_TOOSMALL", "NFS3ERR_XDEV", "NFS3ERR_STALE", 30 | "UNSTABLE", "DATA_SYNC", "FILE_SYNC", "DONT_CHANGE", "SET_TO_CLIENT_TIME", "SET_TO_SERVER_TIME", 31 | "UNCHECKED", "GUARDED", "EXCLUSIVE", "FTYPE3", "NF3REG", "NF3DIR", "NF3BLK", "NF3CHR", "NF3LNK", 32 | "NF3FIFO", "NF3SOCK", "NFS_PROGRAM", "NFS_V3", "MOUNT_V3", "ACCESS3_READ", "ACCESS3_LOOKUP", 33 | "ACCESS3_MODIFY", "ACCESS3_EXTEND", "ACCESS3_DELETE", "ACCESS3_EXECUTE", "release_all_rpc") 34 | -------------------------------------------------------------------------------- /pyNfsClient/const.py: -------------------------------------------------------------------------------- 1 | # GENERAL 2 | FALSE = 0 3 | TRUE = 1 4 | 5 | # PORT MAP 6 | PORTMAP_PROGRAM = 100000 7 | PORTMAP_VERSION = 2 8 | PORTMAP_PORT = 111 9 | 10 | # MOUNT RELATED 11 | MOUNT_PROGRAM = 100005 12 | MOUNT_V3 = 3 13 | MNT3_OK = 0 14 | MNT3ERR_PERM = 1 15 | MNT3ERR_NOENT = 2 16 | MNT3ERR_IO = 5 17 | MNT3ERR_ACCES = 13 18 | MNT3ERR_NOTDIR = 20 19 | MNT3ERR_INVAL = 22 20 | MNT3ERR_NAMETOOLONG = 63 21 | MNT3ERR_NOTSUPP = 10004 22 | MNT3ERR_SERVERFAULT = 10006 23 | MOUNTSTAT3 = { 24 | 0: 'MNT3_OK', 25 | 1: 'MNT3ERR_PERM', 26 | 2: 'MNT3ERR_NOENT', 27 | 5: 'MNT3ERR_IO', 28 | 13: 'MNT3ERR_ACCES', 29 | 20: 'MNT3ERR_NOTDIR', 30 | 22: 'MNT3ERR_INVAL', 31 | 63: 'MNT3ERR_NAMETOOLONG', 32 | 10004: 'MNT3ERR_NOTSUPP', 33 | 10006: 'MNT3ERR_SERVERFAULT', 34 | } 35 | 36 | # --------------- 37 | # NFS V3 RELATED 38 | # --------------- 39 | NFS_PROGRAM = 100003 40 | NFS_V3 = 3 41 | NFS3_MNTPATHLEN = 1024 42 | NFS3_MNTNAMLEN = 255 43 | # PROCEDURES 44 | NFS3_PROCEDURE_NULL = 0 45 | NFS3_PROCEDURE_GETATTR = 1 46 | NFS3_PROCEDURE_SETATTR = 2 47 | NFS3_PROCEDURE_LOOKUP = 3 48 | NFS3_PROCEDURE_ACCESS = 4 49 | NFS3_PROCEDURE_READLINK = 5 50 | NFS3_PROCEDURE_READ = 6 51 | NFS3_PROCEDURE_WRITE = 7 52 | NFS3_PROCEDURE_CREATE = 8 53 | NFS3_PROCEDURE_MKDIR = 9 54 | NFS3_PROCEDURE_SYMLINK = 10 55 | NFS3_PROCEDURE_MKNOD = 11 56 | NFS3_PROCEDURE_REMOVE = 12 57 | NFS3_PROCEDURE_RMDIR = 13 58 | NFS3_PROCEDURE_RENAME = 14 59 | NFS3_PROCEDURE_LINK = 15 60 | NFS3_PROCEDURE_READDIR = 16 61 | NFS3_PROCEDURE_READDIRPLUS = 17 62 | NFS3_PROCEDURE_FSSTAT = 18 63 | NFS3_PROCEDURE_FSINFO = 19 64 | NFS3_PROCEDURE_PATHCONF = 20 65 | NFS3_PROCEDURE_COMMIT = 21 66 | 67 | NFS3_FHSIZE = 64 68 | NFS3_COOKIEVERFSIZE = 8 69 | NFS3_CREATEVERFSIZE = 8 70 | NFS3_WRITEVERFSIZE = 8 71 | NFS3_OK = 0 72 | NFS3ERR_PERM = 1 73 | NFS3ERR_NOENT = 2 74 | NFS3ERR_IO = 5 75 | NFS3ERR_NXIO = 6 76 | NFS3ERR_ACCES = 13 77 | NFS3ERR_EXIST = 17 78 | NFS3ERR_XDEV = 18 79 | NFS3ERR_NODEV = 19 80 | NFS3ERR_NOTDIR = 20 81 | NFS3ERR_ISDIR = 21 82 | NFS3ERR_INVAL = 22 83 | NFS3ERR_FBIG = 27 84 | NFS3ERR_NOSPC = 28 85 | NFS3ERR_ROFS = 30 86 | NFS3ERR_MLINK = 31 87 | NFS3ERR_NAMETOOLONG = 63 88 | NFS3ERR_NOTEMPTY = 66 89 | NFS3ERR_DQUOT = 69 90 | NFS3ERR_STALE = 70 91 | NFS3ERR_REMOTE = 71 92 | NFS3ERR_BADHANDLE = 10001 93 | NFS3ERR_NOT_SYNC = 10002 94 | NFS3ERR_BAD_COOKIE = 10003 95 | NFS3ERR_NOTSUPP = 10004 96 | NFS3ERR_TOOSMALL = 10005 97 | NFS3ERR_SERVERFAULT = 10006 98 | NFS3ERR_BADTYPE = 10007 99 | NFS3ERR_JUKEBOX = 10008 100 | NFSSTAT3 = { 101 | 0: 'NFS3_OK', 102 | 1: 'NFS3ERR_PERM', 103 | 2: 'NFS3ERR_NOENT', 104 | 5: 'NFS3ERR_IO', 105 | 6: 'NFS3ERR_NXIO', 106 | 13: 'NFS3ERR_ACCES', 107 | 17: 'NFS3ERR_EXIST', 108 | 18: 'NFS3ERR_XDEV', 109 | 19: 'NFS3ERR_NODEV', 110 | 20: 'NFS3ERR_NOTDIR', 111 | 21: 'NFS3ERR_ISDIR', 112 | 22: 'NFS3ERR_INVAL', 113 | 27: 'NFS3ERR_FBIG', 114 | 28: 'NFS3ERR_NOSPC', 115 | 30: 'NFS3ERR_ROFS', 116 | 31: 'NFS3ERR_MLINK', 117 | 63: 'NFS3ERR_NAMETOOLONG', 118 | 66: 'NFS3ERR_NOTEMPTY', 119 | 69: 'NFS3ERR_DQUOT', 120 | 70: 'NFS3ERR_STALE', 121 | 71: 'NFS3ERR_REMOTE', 122 | 10001: 'NFS3ERR_BADHANDLE', 123 | 10002: 'NFS3ERR_NOT_SYNC', 124 | 10003: 'NFS3ERR_BAD_COOKIE', 125 | 10004: 'NFS3ERR_NOTSUPP', 126 | 10005: 'NFS3ERR_TOOSMALL', 127 | 10006: 'NFS3ERR_SERVERFAULT', 128 | 10007: 'NFS3ERR_BADTYPE', 129 | 10008: 'NFS3ERR_JUKEBOX', 130 | } 131 | NF3REG = 1 132 | NF3DIR = 2 133 | NF3BLK = 3 134 | NF3CHR = 4 135 | NF3LNK = 5 136 | NF3SOCK = 6 137 | NF3FIFO = 7 138 | FTYPE3 = { 139 | 1: 'NF3REG', 140 | 2: 'NF3DIR', 141 | 3: 'NF3BLK', 142 | 4: 'NF3CHR', 143 | 5: 'NF3LNK', 144 | 6: 'NF3SOCK', 145 | 7: 'NF3FIFO', 146 | } 147 | DONT_CHANGE = 0 148 | SET_TO_SERVER_TIME = 1 149 | SET_TO_CLIENT_TIME = 2 150 | time_how = { 151 | 0: 'DONT_CHANGE', 152 | 1: 'SET_TO_SERVER_TIME', 153 | 2: 'SET_TO_CLIENT_TIME', 154 | } 155 | ACCESS3_READ = 0x0001 156 | ACCESS3_LOOKUP = 0x0002 157 | ACCESS3_MODIFY = 0x0004 158 | ACCESS3_EXTEND = 0x0008 159 | ACCESS3_DELETE = 0x0010 160 | ACCESS3_EXECUTE = 0x0020 161 | UNSTABLE = 0 162 | DATA_SYNC = 1 163 | FILE_SYNC = 2 164 | STABLE_HOW = { 165 | 0: 'UNSTABLE', 166 | 1: 'DATA_SYNC', 167 | 2: 'FILE_SYNC', 168 | } 169 | UNCHECKED = 0 170 | GUARDED = 1 171 | EXCLUSIVE = 2 172 | CREATEMODE3 = { 173 | 0: 'UNCHECKED', 174 | 1: 'GUARDED', 175 | 2: 'EXCLUSIVE', 176 | } 177 | FSF3_LINK = 0x0001 178 | FSF3_SYMLINK = 0x0002 179 | FSF3_HOMOGENEOUS = 0x0008 180 | FSF3_CANSETTIME = 0x0010 181 | 182 | # --------- 183 | # NFS v4.2 184 | # --------- 185 | nfs_bool = { 186 | 0: "FALSE", 187 | 1: "TRUE", 188 | } 189 | 190 | # Sizes 191 | NFS4_FHSIZE = 128 192 | NFS4_VERIFIER_SIZE = 8 193 | NFS4_OPAQUE_LIMIT = 1024 194 | NFS4_OTHER_SIZE = 12 195 | # Sizes new to NFSv4.1 196 | NFS4_SESSIONID_SIZE = 16 197 | NFS4_DEVICEID4_SIZE = 16 198 | NFS4_INT64_MAX = 0x7fffffffffffffff 199 | NFS4_UINT64_MAX = 0xffffffffffffffff 200 | NFS4_INT32_MAX = 0x7fffffff 201 | NFS4_UINT32_MAX = 0xffffffff 202 | 203 | # Enum nfs_ftype4 204 | NF4REG = 1 # Regular File 205 | NF4DIR = 2 # Directory 206 | NF4BLK = 3 # Special File - block device 207 | NF4CHR = 4 # Special File - character device 208 | NF4LNK = 5 # Symbolic Link 209 | NF4SOCK = 6 # Special File - socket 210 | NF4FIFO = 7 # Special File - fifo 211 | NF4ATTRDIR = 8 # Attribute Directory 212 | NF4NAMEDATTR = 9 # Named Attribute 213 | 214 | nfs_ftype4 = { 215 | 1: "NF4REG", 216 | 2: "NF4DIR", 217 | 3: "NF4BLK", 218 | 4: "NF4CHR", 219 | 5: "NF4LNK", 220 | 6: "NF4SOCK", 221 | 7: "NF4FIFO", 222 | 8: "NF4ATTRDIR", 223 | 9: "NF4NAMEDATTR", 224 | } 225 | 226 | # Enum nfsstat4 227 | NFS4_OK = 0 # everything is okay 228 | NFS4ERR_PERM = 1 # caller not privileged 229 | NFS4ERR_NOENT = 2 # no such file/directory 230 | NFS4ERR_IO = 5 # hard I/O error 231 | NFS4ERR_NXIO = 6 # no such device 232 | NFS4ERR_ACCESS = 13 # access denied 233 | NFS4ERR_EXIST = 17 # file already exists 234 | NFS4ERR_XDEV = 18 # different filesystems 235 | # Unused/reserved 19 236 | NFS4ERR_NOTDIR = 20 # should be a directory 237 | NFS4ERR_ISDIR = 21 # should not be directory 238 | NFS4ERR_INVAL = 22 # invalid argument 239 | NFS4ERR_FBIG = 27 # file exceeds server max 240 | NFS4ERR_NOSPC = 28 # no space on filesystem 241 | NFS4ERR_ROFS = 30 # read-only filesystem 242 | NFS4ERR_MLINK = 31 # too many hard links 243 | NFS4ERR_NAMETOOLONG = 63 # name exceeds server max 244 | NFS4ERR_NOTEMPTY = 66 # directory not empty 245 | NFS4ERR_DQUOT = 69 # hard quota limit reached 246 | NFS4ERR_STALE = 70 # file no longer exists 247 | NFS4ERR_BADHANDLE = 10001 # Illegal filehandle 248 | NFS4ERR_BAD_COOKIE = 10003 # READDIR cookie is stale 249 | NFS4ERR_NOTSUPP = 10004 # operation not supported 250 | NFS4ERR_TOOSMALL = 10005 # response limit exceeded 251 | NFS4ERR_SERVERFAULT = 10006 # undefined server error 252 | NFS4ERR_BADTYPE = 10007 # type invalid for CREATE 253 | NFS4ERR_DELAY = 10008 # file "busy" - retry 254 | NFS4ERR_SAME = 10009 # nverify says attrs same 255 | NFS4ERR_DENIED = 10010 # lock unavailable 256 | NFS4ERR_EXPIRED = 10011 # lock lease expired 257 | NFS4ERR_LOCKED = 10012 # I/O failed due to lock 258 | NFS4ERR_GRACE = 10013 # in grace period 259 | NFS4ERR_FHEXPIRED = 10014 # filehandle expired 260 | NFS4ERR_SHARE_DENIED = 10015 # share reserve denied 261 | NFS4ERR_WRONGSEC = 10016 # wrong security flavor 262 | NFS4ERR_CLID_INUSE = 10017 # clientid in use 263 | # NFS4ERR_RESOURCE is not a valid error in NFSv4.1 264 | NFS4ERR_RESOURCE = 10018 # resource exhaustion 265 | NFS4ERR_MOVED = 10019 # filesystem relocated 266 | NFS4ERR_NOFILEHANDLE = 10020 # current FH is not set 267 | NFS4ERR_MINOR_VERS_MISMATCH = 10021 # minor vers not supp 268 | NFS4ERR_STALE_CLIENTID = 10022 # server has rebooted 269 | NFS4ERR_STALE_STATEID = 10023 # server has rebooted 270 | NFS4ERR_OLD_STATEID = 10024 # state is out of sync 271 | NFS4ERR_BAD_STATEID = 10025 # incorrect stateid 272 | NFS4ERR_BAD_SEQID = 10026 # request is out of seq. 273 | NFS4ERR_NOT_SAME = 10027 # verify - attrs not same 274 | NFS4ERR_LOCK_RANGE = 10028 # overlapping lock range 275 | NFS4ERR_SYMLINK = 10029 # should be file/directory 276 | NFS4ERR_RESTOREFH = 10030 # no saved filehandle 277 | NFS4ERR_LEASE_MOVED = 10031 # some filesystem moved 278 | NFS4ERR_ATTRNOTSUPP = 10032 # recommended attr not sup 279 | NFS4ERR_NO_GRACE = 10033 # reclaim outside of grace 280 | NFS4ERR_RECLAIM_BAD = 10034 # reclaim error at server 281 | NFS4ERR_RECLAIM_CONFLICT = 10035 # conflict on reclaim 282 | NFS4ERR_BADXDR = 10036 # XDR decode failed 283 | NFS4ERR_LOCKS_HELD = 10037 # file locks held at CLOSE 284 | NFS4ERR_OPENMODE = 10038 # conflict in OPEN and I/O 285 | NFS4ERR_BADOWNER = 10039 # owner translation bad 286 | NFS4ERR_BADCHAR = 10040 # utf-8 char not supported 287 | NFS4ERR_BADNAME = 10041 # name not supported 288 | NFS4ERR_BAD_RANGE = 10042 # lock range not supported 289 | NFS4ERR_LOCK_NOTSUPP = 10043 # no atomic up/downgrade 290 | NFS4ERR_OP_ILLEGAL = 10044 # undefined operation 291 | NFS4ERR_DEADLOCK = 10045 # file locking deadlock 292 | NFS4ERR_FILE_OPEN = 10046 # open file blocks op. 293 | NFS4ERR_ADMIN_REVOKED = 10047 # lockowner state revoked 294 | NFS4ERR_CB_PATH_DOWN = 10048 # callback path down 295 | 296 | # NFSv4.1 errors start here 297 | NFS4ERR_BADIOMODE = 10049 298 | NFS4ERR_BADLAYOUT = 10050 299 | NFS4ERR_BAD_SESSION_DIGEST = 10051 300 | NFS4ERR_BADSESSION = 10052 301 | NFS4ERR_BADSLOT = 10053 302 | NFS4ERR_COMPLETE_ALREADY = 10054 303 | NFS4ERR_CONN_NOT_BOUND_TO_SESSION = 10055 304 | NFS4ERR_DELEG_ALREADY_WANTED = 10056 305 | NFS4ERR_BACK_CHAN_BUSY = 10057 # backchan reqs outstanding 306 | NFS4ERR_LAYOUTTRYLATER = 10058 307 | NFS4ERR_LAYOUTUNAVAILABLE = 10059 308 | NFS4ERR_NOMATCHING_LAYOUT = 10060 309 | NFS4ERR_RECALLCONFLICT = 10061 310 | NFS4ERR_UNKNOWN_LAYOUTTYPE = 10062 311 | NFS4ERR_SEQ_MISORDERED = 10063 # unexpected seq.id in req 312 | NFS4ERR_SEQUENCE_POS = 10064 # [CB_]SEQ. op not 1st op 313 | NFS4ERR_REQ_TOO_BIG = 10065 # request too big 314 | NFS4ERR_REP_TOO_BIG = 10066 # reply too big 315 | NFS4ERR_REP_TOO_BIG_TO_CACHE = 10067 # rep. not all cached 316 | NFS4ERR_RETRY_UNCACHED_REP = 10068 # retry & rep. uncached 317 | NFS4ERR_UNSAFE_COMPOUND = 10069 # retry/recovery too hard 318 | NFS4ERR_TOO_MANY_OPS = 10070 # too many ops in [CB_]COMP 319 | NFS4ERR_OP_NOT_IN_SESSION = 10071 # op needs [CB_]SEQ. op 320 | NFS4ERR_HASH_ALG_UNSUPP = 10072 # hash alg. not supp. 321 | # Unused/reserved 10073 322 | NFS4ERR_CLIENTID_BUSY = 10074 # clientid has state 323 | NFS4ERR_PNFS_IO_HOLE = 10075 # IO to _SPARSE file hole 324 | NFS4ERR_SEQ_FALSE_RETRY = 10076 # Retry != original req. 325 | NFS4ERR_BAD_HIGH_SLOT = 10077 # req has bad highest_slot 326 | NFS4ERR_DEADSESSION = 10078 # new req sent to dead sess 327 | NFS4ERR_ENCR_ALG_UNSUPP = 10079 # encr alg. not supp. 328 | NFS4ERR_PNFS_NO_LAYOUT = 10080 # I/O without a layout 329 | NFS4ERR_NOT_ONLY_OP = 10081 # addl ops not allowed 330 | NFS4ERR_WRONG_CRED = 10082 # op done by wrong cred 331 | NFS4ERR_WRONG_TYPE = 10083 # op on wrong type object 332 | NFS4ERR_DIRDELEG_UNAVAIL = 10084 # delegation not avail. 333 | NFS4ERR_REJECT_DELEG = 10085 # cb rejected delegation 334 | NFS4ERR_RETURNCONFLICT = 10086 # layout get before return 335 | NFS4ERR_DELEG_REVOKED = 10087 # no return-state revoked 336 | 337 | # NFSv4.2 errors start here 338 | NFS4ERR_PARTNER_NOTSUPP = 10088 # s2s not supported 339 | NFS4ERR_PARTNER_NO_AUTH = 10089 # s2s not authorized 340 | NFS4ERR_UNION_NOTSUPP = 10090 # Arm of union not supp 341 | NFS4ERR_OFFLOAD_DENIED = 10091 # dest not allowing copy 342 | NFS4ERR_WRONG_LFS = 10092 # LFS not supported 343 | NFS4ERR_BADLABEL = 10093 # incorrect label 344 | NFS4ERR_OFFLOAD_NO_REQS = 10094 # dest not meeting reqs 345 | 346 | nfsstat4 = { 347 | 0: "NFS4_OK", 348 | 1: "NFS4ERR_PERM", 349 | 2: "NFS4ERR_NOENT", 350 | 5: "NFS4ERR_IO", 351 | 6: "NFS4ERR_NXIO", 352 | 13: "NFS4ERR_ACCESS", 353 | 17: "NFS4ERR_EXIST", 354 | 18: "NFS4ERR_XDEV", 355 | 20: "NFS4ERR_NOTDIR", 356 | 21: "NFS4ERR_ISDIR", 357 | 22: "NFS4ERR_INVAL", 358 | 27: "NFS4ERR_FBIG", 359 | 28: "NFS4ERR_NOSPC", 360 | 30: "NFS4ERR_ROFS", 361 | 31: "NFS4ERR_MLINK", 362 | 63: "NFS4ERR_NAMETOOLONG", 363 | 66: "NFS4ERR_NOTEMPTY", 364 | 69: "NFS4ERR_DQUOT", 365 | 70: "NFS4ERR_STALE", 366 | 10001: "NFS4ERR_BADHANDLE", 367 | 10003: "NFS4ERR_BAD_COOKIE", 368 | 10004: "NFS4ERR_NOTSUPP", 369 | 10005: "NFS4ERR_TOOSMALL", 370 | 10006: "NFS4ERR_SERVERFAULT", 371 | 10007: "NFS4ERR_BADTYPE", 372 | 10008: "NFS4ERR_DELAY", 373 | 10009: "NFS4ERR_SAME", 374 | 10010: "NFS4ERR_DENIED", 375 | 10011: "NFS4ERR_EXPIRED", 376 | 10012: "NFS4ERR_LOCKED", 377 | 10013: "NFS4ERR_GRACE", 378 | 10014: "NFS4ERR_FHEXPIRED", 379 | 10015: "NFS4ERR_SHARE_DENIED", 380 | 10016: "NFS4ERR_WRONGSEC", 381 | 10017: "NFS4ERR_CLID_INUSE", 382 | 10018: "NFS4ERR_RESOURCE", 383 | 10019: "NFS4ERR_MOVED", 384 | 10020: "NFS4ERR_NOFILEHANDLE", 385 | 10021: "NFS4ERR_MINOR_VERS_MISMATCH", 386 | 10022: "NFS4ERR_STALE_CLIENTID", 387 | 10023: "NFS4ERR_STALE_STATEID", 388 | 10024: "NFS4ERR_OLD_STATEID", 389 | 10025: "NFS4ERR_BAD_STATEID", 390 | 10026: "NFS4ERR_BAD_SEQID", 391 | 10027: "NFS4ERR_NOT_SAME", 392 | 10028: "NFS4ERR_LOCK_RANGE", 393 | 10029: "NFS4ERR_SYMLINK", 394 | 10030: "NFS4ERR_RESTOREFH", 395 | 10031: "NFS4ERR_LEASE_MOVED", 396 | 10032: "NFS4ERR_ATTRNOTSUPP", 397 | 10033: "NFS4ERR_NO_GRACE", 398 | 10034: "NFS4ERR_RECLAIM_BAD", 399 | 10035: "NFS4ERR_RECLAIM_CONFLICT", 400 | 10036: "NFS4ERR_BADXDR", 401 | 10037: "NFS4ERR_LOCKS_HELD", 402 | 10038: "NFS4ERR_OPENMODE", 403 | 10039: "NFS4ERR_BADOWNER", 404 | 10040: "NFS4ERR_BADCHAR", 405 | 10041: "NFS4ERR_BADNAME", 406 | 10042: "NFS4ERR_BAD_RANGE", 407 | 10043: "NFS4ERR_LOCK_NOTSUPP", 408 | 10044: "NFS4ERR_OP_ILLEGAL", 409 | 10045: "NFS4ERR_DEADLOCK", 410 | 10046: "NFS4ERR_FILE_OPEN", 411 | 10047: "NFS4ERR_ADMIN_REVOKED", 412 | 10048: "NFS4ERR_CB_PATH_DOWN", 413 | 10049: "NFS4ERR_BADIOMODE", 414 | 10050: "NFS4ERR_BADLAYOUT", 415 | 10051: "NFS4ERR_BAD_SESSION_DIGEST", 416 | 10052: "NFS4ERR_BADSESSION", 417 | 10053: "NFS4ERR_BADSLOT", 418 | 10054: "NFS4ERR_COMPLETE_ALREADY", 419 | 10055: "NFS4ERR_CONN_NOT_BOUND_TO_SESSION", 420 | 10056: "NFS4ERR_DELEG_ALREADY_WANTED", 421 | 10057: "NFS4ERR_BACK_CHAN_BUSY", 422 | 10058: "NFS4ERR_LAYOUTTRYLATER", 423 | 10059: "NFS4ERR_LAYOUTUNAVAILABLE", 424 | 10060: "NFS4ERR_NOMATCHING_LAYOUT", 425 | 10061: "NFS4ERR_RECALLCONFLICT", 426 | 10062: "NFS4ERR_UNKNOWN_LAYOUTTYPE", 427 | 10063: "NFS4ERR_SEQ_MISORDERED", 428 | 10064: "NFS4ERR_SEQUENCE_POS", 429 | 10065: "NFS4ERR_REQ_TOO_BIG", 430 | 10066: "NFS4ERR_REP_TOO_BIG", 431 | 10067: "NFS4ERR_REP_TOO_BIG_TO_CACHE", 432 | 10068: "NFS4ERR_RETRY_UNCACHED_REP", 433 | 10069: "NFS4ERR_UNSAFE_COMPOUND", 434 | 10070: "NFS4ERR_TOO_MANY_OPS", 435 | 10071: "NFS4ERR_OP_NOT_IN_SESSION", 436 | 10072: "NFS4ERR_HASH_ALG_UNSUPP", 437 | 10074: "NFS4ERR_CLIENTID_BUSY", 438 | 10075: "NFS4ERR_PNFS_IO_HOLE", 439 | 10076: "NFS4ERR_SEQ_FALSE_RETRY", 440 | 10077: "NFS4ERR_BAD_HIGH_SLOT", 441 | 10078: "NFS4ERR_DEADSESSION", 442 | 10079: "NFS4ERR_ENCR_ALG_UNSUPP", 443 | 10080: "NFS4ERR_PNFS_NO_LAYOUT", 444 | 10081: "NFS4ERR_NOT_ONLY_OP", 445 | 10082: "NFS4ERR_WRONG_CRED", 446 | 10083: "NFS4ERR_WRONG_TYPE", 447 | 10084: "NFS4ERR_DIRDELEG_UNAVAIL", 448 | 10085: "NFS4ERR_REJECT_DELEG", 449 | 10086: "NFS4ERR_RETURNCONFLICT", 450 | 10087: "NFS4ERR_DELEG_REVOKED", 451 | 10088: "NFS4ERR_PARTNER_NOTSUPP", 452 | 10089: "NFS4ERR_PARTNER_NO_AUTH", 453 | 10090: "NFS4ERR_UNION_NOTSUPP", 454 | 10091: "NFS4ERR_OFFLOAD_DENIED", 455 | 10092: "NFS4ERR_WRONG_LFS", 456 | 10093: "NFS4ERR_BADLABEL", 457 | 10094: "NFS4ERR_OFFLOAD_NO_REQS", 458 | } 459 | 460 | # Enum time_how4 461 | SET_TO_SERVER_TIME4 = 0 462 | SET_TO_CLIENT_TIME4 = 1 463 | 464 | time_how4 = { 465 | 0: "SET_TO_SERVER_TIME4", 466 | 1: "SET_TO_CLIENT_TIME4", 467 | } 468 | 469 | # Various Access Control Entry definitions 470 | # 471 | # Mask that indicates which Access Control Entries are supported. 472 | # Values for the fattr4_aclsupport attribute. 473 | ACL4_SUPPORT_ALLOW_ACL = 0x00000001 474 | ACL4_SUPPORT_DENY_ACL = 0x00000002 475 | ACL4_SUPPORT_AUDIT_ACL = 0x00000004 476 | ACL4_SUPPORT_ALARM_ACL = 0x00000008 477 | 478 | # acetype4 values, others can be added as needed. 479 | ACE4_ACCESS_ALLOWED_ACE_TYPE = 0x00000000 480 | ACE4_ACCESS_DENIED_ACE_TYPE = 0x00000001 481 | ACE4_SYSTEM_AUDIT_ACE_TYPE = 0x00000002 482 | ACE4_SYSTEM_ALARM_ACE_TYPE = 0x00000003 483 | 484 | # ACE flag values 485 | ACE4_FILE_INHERIT_ACE = 0x00000001 486 | ACE4_DIRECTORY_INHERIT_ACE = 0x00000002 487 | ACE4_NO_PROPAGATE_INHERIT_ACE = 0x00000004 488 | ACE4_INHERIT_ONLY_ACE = 0x00000008 489 | ACE4_SUCCESSFUL_ACCESS_ACE_FLAG = 0x00000010 490 | ACE4_FAILED_ACCESS_ACE_FLAG = 0x00000020 491 | ACE4_IDENTIFIER_GROUP = 0x00000040 492 | ACE4_INHERITED_ACE = 0x00000080 # New to NFSv4.1 493 | 494 | # ACE mask values 495 | ACE4_READ_DATA = 0x00000001 496 | ACE4_LIST_DIRECTORY = 0x00000001 497 | ACE4_WRITE_DATA = 0x00000002 498 | ACE4_ADD_FILE = 0x00000002 499 | ACE4_APPEND_DATA = 0x00000004 500 | ACE4_ADD_SUBDIRECTORY = 0x00000004 501 | ACE4_READ_NAMED_ATTRS = 0x00000008 502 | ACE4_WRITE_NAMED_ATTRS = 0x00000010 503 | ACE4_EXECUTE = 0x00000020 504 | ACE4_DELETE_CHILD = 0x00000040 505 | ACE4_READ_ATTRIBUTES = 0x00000080 506 | ACE4_WRITE_ATTRIBUTES = 0x00000100 507 | ACE4_WRITE_RETENTION = 0x00000200 # New to NFSv4.1 508 | ACE4_WRITE_RETENTION_HOLD = 0x00000400 # New to NFSv4.1 509 | ACE4_DELETE = 0x00010000 510 | ACE4_READ_ACL = 0x00020000 511 | ACE4_WRITE_ACL = 0x00040000 512 | ACE4_WRITE_OWNER = 0x00080000 513 | ACE4_SYNCHRONIZE = 0x00100000 514 | 515 | # ACE4_GENERIC_READ -- defined as combination of 516 | # ACE4_READ_ACL | 517 | # ACE4_READ_DATA | 518 | # ACE4_READ_ATTRIBUTES | 519 | # ACE4_SYNCHRONIZE 520 | ACE4_GENERIC_READ = 0x00120081 521 | 522 | # ACE4_GENERIC_WRITE -- defined as combination of 523 | # ACE4_READ_ACL | 524 | # ACE4_WRITE_DATA | 525 | # ACE4_WRITE_ATTRIBUTES | 526 | # ACE4_WRITE_ACL | 527 | # ACE4_APPEND_DATA | 528 | # ACE4_SYNCHRONIZE 529 | ACE4_GENERIC_WRITE = 0x00160106 530 | 531 | # ACE4_GENERIC_EXECUTE -- defined as combination of 532 | # ACE4_READ_ACL 533 | # ACE4_READ_ATTRIBUTES 534 | # ACE4_EXECUTE 535 | # ACE4_SYNCHRONIZE 536 | ACE4_GENERIC_EXECUTE = 0x001200A0 537 | 538 | # ACL flag values new to NFSv4.1 539 | ACL4_AUTO_INHERIT = 0x00000001 540 | ACL4_PROTECTED = 0x00000002 541 | ACL4_DEFAULTED = 0x00000004 542 | 543 | # Field definitions for the fattr4_mode attribute 544 | # and fattr4_mode_set_masked attributes. 545 | MODE4_SUID = 0x800 # set user id on execution 546 | MODE4_SGID = 0x400 # set group id on execution 547 | MODE4_SVTX = 0x200 # save text even after use 548 | MODE4_RUSR = 0x100 # read permission: owner 549 | MODE4_WUSR = 0x080 # write permission: owner 550 | MODE4_XUSR = 0x040 # execute permission: owner 551 | MODE4_RGRP = 0x020 # read permission: group 552 | MODE4_WGRP = 0x010 # write permission: group 553 | MODE4_XGRP = 0x008 # execute permission: group 554 | MODE4_ROTH = 0x004 # read permission: other 555 | MODE4_WOTH = 0x002 # write permission: other 556 | MODE4_XOTH = 0x001 # execute permission: other 557 | 558 | # Enum stable_how4 559 | UNSTABLE4 = 0 560 | DATA_SYNC4 = 1 561 | FILE_SYNC4 = 2 562 | 563 | stable_how4 = { 564 | 0: "UNSTABLE4", 565 | 1: "DATA_SYNC4", 566 | 2: "FILE_SYNC4", 567 | } 568 | 569 | # Values for fattr4_fh_expire_type 570 | FH4_PERSISTENT = 0x00000000 571 | FH4_NOEXPIRE_WITH_OPEN = 0x00000001 572 | FH4_VOLATILE_ANY = 0x00000002 573 | FH4_VOL_MIGRATION = 0x00000004 574 | FH4_VOL_RENAME = 0x00000008 575 | 576 | # Enum layouttype4 577 | LAYOUT4_NFSV4_1_FILES = 0x1 578 | LAYOUT4_OSD2_OBJECTS = 0x2 579 | LAYOUT4_BLOCK_VOLUME = 0x3 580 | LAYOUT4_FLEX_FILES = 0x4 581 | 582 | layouttype4 = { 583 | 0x1: "LAYOUT4_NFSV4_1_FILES", 584 | 0x2: "LAYOUT4_OSD2_OBJECTS", 585 | 0x3: "LAYOUT4_BLOCK_VOLUME", 586 | 0x4: "LAYOUT4_FLEX_FILES", 587 | } 588 | 589 | NFL4_UFLG_MASK = 0x0000003F 590 | NFL4_UFLG_DENSE = 0x00000001 591 | NFL4_UFLG_COMMIT_THRU_MDS = 0x00000002 592 | NFL42_UFLG_IO_ADVISE_THRU_MDS = 0x00000004 593 | NFL4_UFLG_STRIPE_UNIT_SIZE_MASK = 0xFFFFFFC0 594 | 595 | # Enum filelayout_hint_care4 596 | NFLH4_CARE_DENSE = NFL4_UFLG_DENSE 597 | NFLH4_CARE_COMMIT_THRU_MDS = NFL4_UFLG_COMMIT_THRU_MDS 598 | NFL42_CARE_IO_ADVISE_THRU_MDS = NFL42_UFLG_IO_ADVISE_THRU_MDS 599 | NFLH4_CARE_STRIPE_UNIT_SIZE = 0x00000040 600 | NFLH4_CARE_STRIPE_COUNT = 0x00000080 601 | 602 | filelayout_hint_care4 = { 603 | NFL4_UFLG_DENSE : "NFLH4_CARE_DENSE", 604 | NFL4_UFLG_COMMIT_THRU_MDS : "NFLH4_CARE_COMMIT_THRU_MDS", 605 | NFL42_UFLG_IO_ADVISE_THRU_MDS : "NFL42_CARE_IO_ADVISE_THRU_MDS", 606 | 0x00000040 : "NFLH4_CARE_STRIPE_UNIT_SIZE", 607 | 0x00000080 : "NFLH4_CARE_STRIPE_COUNT", 608 | } 609 | 610 | # NFSv4.x flex files layout definitions 611 | 612 | FF_FLAGS_NO_LAYOUTCOMMIT = 1 613 | 614 | # Enum ff_cb_recall_any_mask 615 | FF_RCA4_TYPE_MASK_READ = -2 616 | FF_RCA4_TYPE_MASK_RW = -1 617 | 618 | ff_cb_recall_any_mask = { 619 | -2: "FF_RCA4_TYPE_MASK_READ", 620 | -1: "FF_RCA4_TYPE_MASK_RW", 621 | } 622 | 623 | # Enum layoutiomode4 624 | LAYOUTIOMODE4_READ = 1 625 | LAYOUTIOMODE4_RW = 2 626 | LAYOUTIOMODE4_ANY = 3 627 | 628 | layoutiomode4 = { 629 | 1: "LAYOUTIOMODE4_READ", 630 | 2: "LAYOUTIOMODE4_RW", 631 | 3: "LAYOUTIOMODE4_ANY", 632 | } 633 | # Constants used for LAYOUTRETURN and CB_LAYOUTRECALL 634 | LAYOUT4_RET_REC_FILE = 1 635 | LAYOUT4_RET_REC_FSID = 2 636 | LAYOUT4_RET_REC_ALL = 3 637 | 638 | # Enum layoutreturn_type4 639 | LAYOUTRETURN4_FILE = LAYOUT4_RET_REC_FILE 640 | LAYOUTRETURN4_FSID = LAYOUT4_RET_REC_FSID 641 | LAYOUTRETURN4_ALL = LAYOUT4_RET_REC_ALL 642 | 643 | layoutreturn_type4 = { 644 | LAYOUT4_RET_REC_FILE : "LAYOUTRETURN4_FILE", 645 | LAYOUT4_RET_REC_FSID : "LAYOUTRETURN4_FSID", 646 | LAYOUT4_RET_REC_ALL : "LAYOUTRETURN4_ALL", 647 | } 648 | 649 | # Enum fs4_status_type 650 | STATUS4_FIXED = 1 651 | STATUS4_UPDATED = 2 652 | STATUS4_VERSIONED = 3 653 | STATUS4_WRITABLE = 4 654 | STATUS4_REFERRAL = 5 655 | 656 | fs4_status_type = { 657 | 1: "STATUS4_FIXED", 658 | 2: "STATUS4_UPDATED", 659 | 3: "STATUS4_VERSIONED", 660 | 4: "STATUS4_WRITABLE", 661 | 5: "STATUS4_REFERRAL", 662 | } 663 | 664 | TH4_READ_SIZE = 0 665 | TH4_WRITE_SIZE = 1 666 | TH4_READ_IOSIZE = 2 667 | TH4_WRITE_IOSIZE = 3 668 | 669 | RET4_DURATION_INFINITE = 0xffffffffffffffff 670 | 671 | # Byte indices of items within 672 | # fls_info: flag fields, class numbers, 673 | # bytes indicating ranks and orders. 674 | FSLI4BX_GFLAGS = 0 675 | FSLI4BX_TFLAGS = 1 676 | FSLI4BX_CLSIMUL = 2 677 | FSLI4BX_CLHANDLE = 3 678 | FSLI4BX_CLFILEID = 4 679 | FSLI4BX_CLWRITEVER = 5 680 | FSLI4BX_CLCHANGE = 6 681 | FSLI4BX_CLREADDIR = 7 682 | FSLI4BX_READRANK = 8 683 | FSLI4BX_WRITERANK = 9 684 | FSLI4BX_READORDER = 10 685 | FSLI4BX_WRITEORDER = 11 686 | 687 | # Bits defined within the general flag byte. 688 | FSLI4GF_WRITABLE = 0x01 689 | FSLI4GF_CUR_REQ = 0x02 690 | FSLI4GF_ABSENT = 0x04 691 | FSLI4GF_GOING = 0x08 692 | FSLI4GF_SPLIT = 0x10 693 | 694 | # Bits defined within the transport flag byte. 695 | FSLI4TF_RDMA = 0x01 696 | 697 | # Flag bits in fli_flags. 698 | FSLI4IF_VAR_SUB = 0x00000001 699 | # Constants for fs_charset_cap4 700 | FSCHARSET_CAP4_CONTAINS_NON_UTF8 = 0x1 701 | FSCHARSET_CAP4_ALLOWS_ONLY_UTF8 = 0x2 702 | 703 | # Enum netloc_type4 704 | NL4_NAME = 1 705 | NL4_URL = 2 706 | NL4_NETADDR = 3 707 | 708 | netloc_type4 = { 709 | 1: "NL4_NAME", 710 | 2: "NL4_URL", 711 | 3: "NL4_NETADDR", 712 | } 713 | 714 | # Enum change_attr_type4 715 | NFS4_CHANGE_TYPE_IS_MONOTONIC_INCR = 0 716 | NFS4_CHANGE_TYPE_IS_VERSION_COUNTER = 1 717 | NFS4_CHANGE_TYPE_IS_VERSION_COUNTER_NOPNFS = 2 718 | NFS4_CHANGE_TYPE_IS_TIME_METADATA = 3 719 | NFS4_CHANGE_TYPE_IS_UNDEFINED = 4 720 | 721 | change_attr_type4 = { 722 | 0: "NFS4_CHANGE_TYPE_IS_MONOTONIC_INCR", 723 | 1: "NFS4_CHANGE_TYPE_IS_VERSION_COUNTER", 724 | 2: "NFS4_CHANGE_TYPE_IS_VERSION_COUNTER_NOPNFS", 725 | 3: "NFS4_CHANGE_TYPE_IS_TIME_METADATA", 726 | 4: "NFS4_CHANGE_TYPE_IS_UNDEFINED", 727 | } 728 | 729 | # Enum nfs_fattr4 730 | 731 | # Mandatory Attributes 732 | FATTR4_SUPPORTED_ATTRS = 0 733 | FATTR4_TYPE = 1 734 | FATTR4_FH_EXPIRE_TYPE = 2 735 | FATTR4_CHANGE = 3 736 | FATTR4_SIZE = 4 737 | FATTR4_LINK_SUPPORT = 5 738 | FATTR4_SYMLINK_SUPPORT = 6 739 | FATTR4_NAMED_ATTR = 7 740 | FATTR4_FSID = 8 741 | FATTR4_UNIQUE_HANDLES = 9 742 | FATTR4_LEASE_TIME = 10 743 | FATTR4_RDATTR_ERROR = 11 744 | FATTR4_FILEHANDLE = 19 745 | FATTR4_SUPPATTR_EXCLCREAT = 75 # New to NFSv4.1 746 | 747 | # Recommended Attributes 748 | FATTR4_ACL = 12 749 | FATTR4_ACLSUPPORT = 13 750 | FATTR4_ARCHIVE = 14 751 | FATTR4_CANSETTIME = 15 752 | FATTR4_CASE_INSENSITIVE = 16 753 | FATTR4_CASE_PRESERVING = 17 754 | FATTR4_CHOWN_RESTRICTED = 18 755 | FATTR4_FILEID = 20 756 | FATTR4_FILES_AVAIL = 21 757 | FATTR4_FILES_FREE = 22 758 | FATTR4_FILES_TOTAL = 23 759 | FATTR4_FS_LOCATIONS = 24 760 | FATTR4_HIDDEN = 25 761 | FATTR4_HOMOGENEOUS = 26 762 | FATTR4_MAXFILESIZE = 27 763 | FATTR4_MAXLINK = 28 764 | FATTR4_MAXNAME = 29 765 | FATTR4_MAXREAD = 30 766 | FATTR4_MAXWRITE = 31 767 | FATTR4_MIMETYPE = 32 768 | FATTR4_MODE = 33 769 | FATTR4_NO_TRUNC = 34 770 | FATTR4_NUMLINKS = 35 771 | FATTR4_OWNER = 36 772 | FATTR4_OWNER_GROUP = 37 773 | FATTR4_QUOTA_AVAIL_HARD = 38 774 | FATTR4_QUOTA_AVAIL_SOFT = 39 775 | FATTR4_QUOTA_USED = 40 776 | FATTR4_RAWDEV = 41 777 | FATTR4_SPACE_AVAIL = 42 778 | FATTR4_SPACE_FREE = 43 779 | FATTR4_SPACE_TOTAL = 44 780 | FATTR4_SPACE_USED = 45 781 | FATTR4_SYSTEM = 46 782 | FATTR4_TIME_ACCESS = 47 783 | FATTR4_TIME_ACCESS_SET = 48 784 | FATTR4_TIME_BACKUP = 49 785 | FATTR4_TIME_CREATE = 50 786 | FATTR4_TIME_DELTA = 51 787 | FATTR4_TIME_METADATA = 52 788 | FATTR4_TIME_MODIFY = 53 789 | FATTR4_TIME_MODIFY_SET = 54 790 | FATTR4_MOUNTED_ON_FILEID = 55 791 | 792 | # New to NFSv4.1 793 | FATTR4_DIR_NOTIF_DELAY = 56 794 | FATTR4_DIRENT_NOTIF_DELAY = 57 795 | FATTR4_DACL = 58 796 | FATTR4_SACL = 59 797 | FATTR4_CHANGE_POLICY = 60 798 | FATTR4_FS_STATUS = 61 799 | FATTR4_FS_LAYOUT_TYPES = 62 800 | FATTR4_LAYOUT_HINT = 63 801 | FATTR4_LAYOUT_TYPES = 64 802 | FATTR4_LAYOUT_BLKSIZE = 65 803 | FATTR4_LAYOUT_ALIGNMENT = 66 804 | FATTR4_FS_LOCATIONS_INFO = 67 805 | FATTR4_MDSTHRESHOLD = 68 806 | FATTR4_RETENTION_GET = 69 807 | FATTR4_RETENTION_SET = 70 808 | FATTR4_RETENTEVT_GET = 71 809 | FATTR4_RETENTEVT_SET = 72 810 | FATTR4_RETENTION_HOLD = 73 811 | FATTR4_MODE_SET_MASKED = 74 812 | FATTR4_FS_CHARSET_CAP = 76 813 | 814 | # New to NFSv4.2 815 | FATTR4_CLONE_BLKSIZE = 77 816 | FATTR4_SPACE_FREED = 78 817 | FATTR4_CHANGE_ATTR_TYPE = 79 818 | FATTR4_SEC_LABEL = 80 819 | 820 | nfs_fattr4 = { 821 | 0: "FATTR4_SUPPORTED_ATTRS", 822 | 1: "FATTR4_TYPE", 823 | 2: "FATTR4_FH_EXPIRE_TYPE", 824 | 3: "FATTR4_CHANGE", 825 | 4: "FATTR4_SIZE", 826 | 5: "FATTR4_LINK_SUPPORT", 827 | 6: "FATTR4_SYMLINK_SUPPORT", 828 | 7: "FATTR4_NAMED_ATTR", 829 | 8: "FATTR4_FSID", 830 | 9: "FATTR4_UNIQUE_HANDLES", 831 | 10: "FATTR4_LEASE_TIME", 832 | 11: "FATTR4_RDATTR_ERROR", 833 | 12: "FATTR4_ACL", 834 | 13: "FATTR4_ACLSUPPORT", 835 | 14: "FATTR4_ARCHIVE", 836 | 15: "FATTR4_CANSETTIME", 837 | 16: "FATTR4_CASE_INSENSITIVE", 838 | 17: "FATTR4_CASE_PRESERVING", 839 | 18: "FATTR4_CHOWN_RESTRICTED", 840 | 19: "FATTR4_FILEHANDLE", 841 | 20: "FATTR4_FILEID", 842 | 21: "FATTR4_FILES_AVAIL", 843 | 22: "FATTR4_FILES_FREE", 844 | 23: "FATTR4_FILES_TOTAL", 845 | 24: "FATTR4_FS_LOCATIONS", 846 | 25: "FATTR4_HIDDEN", 847 | 26: "FATTR4_HOMOGENEOUS", 848 | 27: "FATTR4_MAXFILESIZE", 849 | 28: "FATTR4_MAXLINK", 850 | 29: "FATTR4_MAXNAME", 851 | 30: "FATTR4_MAXREAD", 852 | 31: "FATTR4_MAXWRITE", 853 | 32: "FATTR4_MIMETYPE", 854 | 33: "FATTR4_MODE", 855 | 34: "FATTR4_NO_TRUNC", 856 | 35: "FATTR4_NUMLINKS", 857 | 36: "FATTR4_OWNER", 858 | 37: "FATTR4_OWNER_GROUP", 859 | 38: "FATTR4_QUOTA_AVAIL_HARD", 860 | 39: "FATTR4_QUOTA_AVAIL_SOFT", 861 | 40: "FATTR4_QUOTA_USED", 862 | 41: "FATTR4_RAWDEV", 863 | 42: "FATTR4_SPACE_AVAIL", 864 | 43: "FATTR4_SPACE_FREE", 865 | 44: "FATTR4_SPACE_TOTAL", 866 | 45: "FATTR4_SPACE_USED", 867 | 46: "FATTR4_SYSTEM", 868 | 47: "FATTR4_TIME_ACCESS", 869 | 48: "FATTR4_TIME_ACCESS_SET", 870 | 49: "FATTR4_TIME_BACKUP", 871 | 50: "FATTR4_TIME_CREATE", 872 | 51: "FATTR4_TIME_DELTA", 873 | 52: "FATTR4_TIME_METADATA", 874 | 53: "FATTR4_TIME_MODIFY", 875 | 54: "FATTR4_TIME_MODIFY_SET", 876 | 55: "FATTR4_MOUNTED_ON_FILEID", 877 | 56: "FATTR4_DIR_NOTIF_DELAY", 878 | 57: "FATTR4_DIRENT_NOTIF_DELAY", 879 | 58: "FATTR4_DACL", 880 | 59: "FATTR4_SACL", 881 | 60: "FATTR4_CHANGE_POLICY", 882 | 61: "FATTR4_FS_STATUS", 883 | 62: "FATTR4_FS_LAYOUT_TYPES", 884 | 63: "FATTR4_LAYOUT_HINT", 885 | 64: "FATTR4_LAYOUT_TYPES", 886 | 65: "FATTR4_LAYOUT_BLKSIZE", 887 | 66: "FATTR4_LAYOUT_ALIGNMENT", 888 | 67: "FATTR4_FS_LOCATIONS_INFO", 889 | 68: "FATTR4_MDSTHRESHOLD", 890 | 69: "FATTR4_RETENTION_GET", 891 | 70: "FATTR4_RETENTION_SET", 892 | 71: "FATTR4_RETENTEVT_GET", 893 | 72: "FATTR4_RETENTEVT_SET", 894 | 73: "FATTR4_RETENTION_HOLD", 895 | 74: "FATTR4_MODE_SET_MASKED", 896 | 75: "FATTR4_SUPPATTR_EXCLCREAT", 897 | 76: "FATTR4_FS_CHARSET_CAP", 898 | 77: "FATTR4_CLONE_BLKSIZE", 899 | 78: "FATTR4_SPACE_FREED", 900 | 79: "FATTR4_CHANGE_ATTR_TYPE", 901 | 80: "FATTR4_SEC_LABEL", 902 | } 903 | 904 | # Enum ssv_subkey4 905 | SSV4_SUBKEY_MIC_I2T = 1 906 | SSV4_SUBKEY_MIC_T2I = 2 907 | SSV4_SUBKEY_SEAL_I2T = 3 908 | SSV4_SUBKEY_SEAL_T2I = 4 909 | 910 | ssv_subkey4 = { 911 | 1: "SSV4_SUBKEY_MIC_I2T", 912 | 2: "SSV4_SUBKEY_MIC_T2I", 913 | 3: "SSV4_SUBKEY_SEAL_I2T", 914 | 4: "SSV4_SUBKEY_SEAL_T2I", 915 | } 916 | 917 | # Enum nfs_opnum4 918 | OP_ACCESS = 3 919 | OP_CLOSE = 4 920 | OP_COMMIT = 5 921 | OP_CREATE = 6 922 | OP_DELEGPURGE = 7 923 | OP_DELEGRETURN = 8 924 | OP_GETATTR = 9 925 | OP_GETFH = 10 926 | OP_LINK = 11 927 | OP_LOCK = 12 928 | OP_LOCKT = 13 929 | OP_LOCKU = 14 930 | OP_LOOKUP = 15 931 | OP_LOOKUPP = 16 932 | OP_NVERIFY = 17 933 | OP_OPEN = 18 934 | OP_OPENATTR = 19 935 | OP_OPEN_CONFIRM = 20 # Mandatory not-to-implement in NFSv4.1 936 | OP_OPEN_DOWNGRADE = 21 937 | OP_PUTFH = 22 938 | OP_PUTPUBFH = 23 939 | OP_PUTROOTFH = 24 940 | OP_READ = 25 941 | OP_READDIR = 26 942 | OP_READLINK = 27 943 | OP_REMOVE = 28 944 | OP_RENAME = 29 945 | OP_RENEW = 30 # Mandatory not-to-implement in NFSv4.1 946 | OP_RESTOREFH = 31 947 | OP_SAVEFH = 32 948 | OP_SECINFO = 33 949 | OP_SETATTR = 34 950 | OP_SETCLIENTID = 35 # Mandatory not-to-implement in NFSv4.1 951 | OP_SETCLIENTID_CONFIRM = 36 # Mandatory not-to-implement in NFSv4.1 952 | OP_VERIFY = 37 953 | OP_WRITE = 38 954 | OP_RELEASE_LOCKOWNER = 39 # Mandatory not-to-implement in NFSv4.1 955 | # New operations for NFSv4.1 956 | OP_BACKCHANNEL_CTL = 40 957 | OP_BIND_CONN_TO_SESSION = 41 958 | OP_EXCHANGE_ID = 42 959 | OP_CREATE_SESSION = 43 960 | OP_DESTROY_SESSION = 44 961 | OP_FREE_STATEID = 45 962 | OP_GET_DIR_DELEGATION = 46 963 | OP_GETDEVICEINFO = 47 964 | OP_GETDEVICELIST = 48 # Mandatory not-to-implement in NFSv4.2 965 | OP_LAYOUTCOMMIT = 49 966 | OP_LAYOUTGET = 50 967 | OP_LAYOUTRETURN = 51 968 | OP_SECINFO_NO_NAME = 52 969 | OP_SEQUENCE = 53 970 | OP_SET_SSV = 54 971 | OP_TEST_STATEID = 55 972 | OP_WANT_DELEGATION = 56 973 | OP_DESTROY_CLIENTID = 57 974 | OP_RECLAIM_COMPLETE = 58 975 | # New operations for NFSv4.2 976 | OP_ALLOCATE = 59 977 | OP_COPY = 60 978 | OP_COPY_NOTIFY = 61 979 | OP_DEALLOCATE = 62 980 | OP_IO_ADVISE = 63 981 | OP_LAYOUTERROR = 64 982 | OP_LAYOUTSTATS = 65 983 | OP_OFFLOAD_CANCEL = 66 984 | OP_OFFLOAD_STATUS = 67 985 | OP_READ_PLUS = 68 986 | OP_SEEK = 69 987 | OP_WRITE_SAME = 70 988 | OP_CLONE = 71 989 | # Illegal operation 990 | OP_ILLEGAL = 10044 991 | 992 | nfs_opnum4 = { 993 | 3: "OP_ACCESS", 994 | 4: "OP_CLOSE", 995 | 5: "OP_COMMIT", 996 | 6: "OP_CREATE", 997 | 7: "OP_DELEGPURGE", 998 | 8: "OP_DELEGRETURN", 999 | 9: "OP_GETATTR", 1000 | 10: "OP_GETFH", 1001 | 11: "OP_LINK", 1002 | 12: "OP_LOCK", 1003 | 13: "OP_LOCKT", 1004 | 14: "OP_LOCKU", 1005 | 15: "OP_LOOKUP", 1006 | 16: "OP_LOOKUPP", 1007 | 17: "OP_NVERIFY", 1008 | 18: "OP_OPEN", 1009 | 19: "OP_OPENATTR", 1010 | 20: "OP_OPEN_CONFIRM", 1011 | 21: "OP_OPEN_DOWNGRADE", 1012 | 22: "OP_PUTFH", 1013 | 23: "OP_PUTPUBFH", 1014 | 24: "OP_PUTROOTFH", 1015 | 25: "OP_READ", 1016 | 26: "OP_READDIR", 1017 | 27: "OP_READLINK", 1018 | 28: "OP_REMOVE", 1019 | 29: "OP_RENAME", 1020 | 30: "OP_RENEW", 1021 | 31: "OP_RESTOREFH", 1022 | 32: "OP_SAVEFH", 1023 | 33: "OP_SECINFO", 1024 | 34: "OP_SETATTR", 1025 | 35: "OP_SETCLIENTID", 1026 | 36: "OP_SETCLIENTID_CONFIRM", 1027 | 37: "OP_VERIFY", 1028 | 38: "OP_WRITE", 1029 | 39: "OP_RELEASE_LOCKOWNER", 1030 | 40: "OP_BACKCHANNEL_CTL", 1031 | 41: "OP_BIND_CONN_TO_SESSION", 1032 | 42: "OP_EXCHANGE_ID", 1033 | 43: "OP_CREATE_SESSION", 1034 | 44: "OP_DESTROY_SESSION", 1035 | 45: "OP_FREE_STATEID", 1036 | 46: "OP_GET_DIR_DELEGATION", 1037 | 47: "OP_GETDEVICEINFO", 1038 | 48: "OP_GETDEVICELIST", 1039 | 49: "OP_LAYOUTCOMMIT", 1040 | 50: "OP_LAYOUTGET", 1041 | 51: "OP_LAYOUTRETURN", 1042 | 52: "OP_SECINFO_NO_NAME", 1043 | 53: "OP_SEQUENCE", 1044 | 54: "OP_SET_SSV", 1045 | 55: "OP_TEST_STATEID", 1046 | 56: "OP_WANT_DELEGATION", 1047 | 57: "OP_DESTROY_CLIENTID", 1048 | 58: "OP_RECLAIM_COMPLETE", 1049 | 59: "OP_ALLOCATE", 1050 | 60: "OP_COPY", 1051 | 61: "OP_COPY_NOTIFY", 1052 | 62: "OP_DEALLOCATE", 1053 | 63: "OP_IO_ADVISE", 1054 | 64: "OP_LAYOUTERROR", 1055 | 65: "OP_LAYOUTSTATS", 1056 | 66: "OP_OFFLOAD_CANCEL", 1057 | 67: "OP_OFFLOAD_STATUS", 1058 | 68: "OP_READ_PLUS", 1059 | 69: "OP_SEEK", 1060 | 70: "OP_WRITE_SAME", 1061 | 71: "OP_CLONE", 1062 | 10044: "OP_ILLEGAL", 1063 | } 1064 | 1065 | ACCESS4_READ = 0x00000001 1066 | ACCESS4_LOOKUP = 0x00000002 1067 | ACCESS4_MODIFY = 0x00000004 1068 | ACCESS4_EXTEND = 0x00000008 1069 | ACCESS4_DELETE = 0x00000010 1070 | ACCESS4_EXECUTE = 0x00000020 1071 | 1072 | # Enum nfs_lock_type4 1073 | READ_LT = 1 1074 | WRITE_LT = 2 1075 | READW_LT = 3 # blocking read 1076 | WRITEW_LT = 4 # blocking write 1077 | 1078 | nfs_lock_type4 = { 1079 | 1: "READ_LT", 1080 | 2: "WRITE_LT", 1081 | 3: "READW_LT", 1082 | 4: "WRITEW_LT", 1083 | } 1084 | 1085 | # Enum createmode4 1086 | UNCHECKED4 = 0 1087 | GUARDED4 = 1 1088 | # Deprecated in NFSv4.1. 1089 | EXCLUSIVE4 = 2 1090 | 1091 | # New to NFSv4.1. If session is persistent, 1092 | # GUARDED4 MUST be used. Otherwise, use 1093 | # EXCLUSIVE4_1 instead of EXCLUSIVE4. 1094 | EXCLUSIVE4_1 = 3 1095 | 1096 | createmode4 = { 1097 | 0: "UNCHECKED4", 1098 | 1: "GUARDED4", 1099 | 2: "EXCLUSIVE4", 1100 | 3: "EXCLUSIVE4_1", 1101 | } 1102 | 1103 | # Enum opentype4 1104 | OPEN4_NOCREATE = 0 1105 | OPEN4_CREATE = 1 1106 | 1107 | opentype4 = { 1108 | 0: "OPEN4_NOCREATE", 1109 | 1: "OPEN4_CREATE", 1110 | } 1111 | 1112 | # Enum limit_by4 1113 | NFS_LIMIT_SIZE = 1 1114 | NFS_LIMIT_BLOCKS = 2 1115 | 1116 | limit_by4 = { 1117 | 1: "NFS_LIMIT_SIZE", 1118 | 2: "NFS_LIMIT_BLOCKS", 1119 | } 1120 | 1121 | # Share Access and Deny constants for open argument 1122 | OPEN4_SHARE_ACCESS_READ = 0x00000001 1123 | OPEN4_SHARE_ACCESS_WRITE = 0x00000002 1124 | OPEN4_SHARE_ACCESS_BOTH = 0x00000003 1125 | OPEN4_SHARE_DENY_NONE = 0x00000000 1126 | OPEN4_SHARE_DENY_READ = 0x00000001 1127 | OPEN4_SHARE_DENY_WRITE = 0x00000002 1128 | OPEN4_SHARE_DENY_BOTH = 0x00000003 1129 | # New flags for share_access field of OPEN4args 1130 | OPEN4_SHARE_ACCESS_WANT_DELEG_MASK = 0xFF00 1131 | OPEN4_SHARE_ACCESS_WANT_NO_PREFERENCE = 0x0000 1132 | OPEN4_SHARE_ACCESS_WANT_READ_DELEG = 0x0100 1133 | OPEN4_SHARE_ACCESS_WANT_WRITE_DELEG = 0x0200 1134 | OPEN4_SHARE_ACCESS_WANT_ANY_DELEG = 0x0300 1135 | OPEN4_SHARE_ACCESS_WANT_NO_DELEG = 0x0400 1136 | OPEN4_SHARE_ACCESS_WANT_CANCEL = 0x0500 1137 | OPEN4_SHARE_ACCESS_WANT_SIGNAL_DELEG_WHEN_RESRC_AVAIL = 0x10000 1138 | OPEN4_SHARE_ACCESS_WANT_PUSH_DELEG_WHEN_UNCONTENDED = 0x20000 1139 | 1140 | # Enum open_delegation_type4 1141 | OPEN_DELEGATE_NONE = 0 1142 | OPEN_DELEGATE_READ = 1 1143 | OPEN_DELEGATE_WRITE = 2 1144 | OPEN_DELEGATE_NONE_EXT = 3 # New to NFSv4.1 1145 | 1146 | open_delegation_type4 = { 1147 | 0: "OPEN_DELEGATE_NONE", 1148 | 1: "OPEN_DELEGATE_READ", 1149 | 2: "OPEN_DELEGATE_WRITE", 1150 | 3: "OPEN_DELEGATE_NONE_EXT", 1151 | } 1152 | 1153 | # Enum open_claim_type4 1154 | 1155 | # Not a reclaim. 1156 | CLAIM_NULL = 0 1157 | CLAIM_PREVIOUS = 1 1158 | CLAIM_DELEGATE_CUR = 2 1159 | CLAIM_DELEGATE_PREV = 3 1160 | 1161 | # Not a reclaim. 1162 | # Like CLAIM_NULL, but object identified 1163 | # by the current filehandle. 1164 | CLAIM_FH = 4 # New to NFSv4.1 1165 | 1166 | # Like CLAIM_DELEGATE_CUR, but object identified 1167 | # by current filehandle. 1168 | CLAIM_DELEG_CUR_FH = 5 # New to NFSv4.1 1169 | 1170 | # Like CLAIM_DELEGATE_PREV, but object identified 1171 | # by current filehandle. 1172 | CLAIM_DELEG_PREV_FH = 6 # New to NFSv4.1 1173 | 1174 | open_claim_type4 = { 1175 | 0: "CLAIM_NULL", 1176 | 1: "CLAIM_PREVIOUS", 1177 | 2: "CLAIM_DELEGATE_CUR", 1178 | 3: "CLAIM_DELEGATE_PREV", 1179 | 4: "CLAIM_FH", 1180 | 5: "CLAIM_DELEG_CUR_FH", 1181 | 6: "CLAIM_DELEG_PREV_FH", 1182 | } 1183 | 1184 | # Enum why_no_delegation4 1185 | WND4_NOT_WANTED = 0 1186 | WND4_CONTENTION = 1 1187 | WND4_RESOURCE = 2 1188 | WND4_NOT_SUPP_FTYPE = 3 1189 | WND4_WRITE_DELEG_NOT_SUPP_FTYPE = 4 1190 | WND4_NOT_SUPP_UPGRADE = 5 1191 | WND4_NOT_SUPP_DOWNGRADE = 6 1192 | WND4_CANCELLED = 7 1193 | WND4_IS_DIR = 8 1194 | 1195 | why_no_delegation4 = { 1196 | 0: "WND4_NOT_WANTED", 1197 | 1: "WND4_CONTENTION", 1198 | 2: "WND4_RESOURCE", 1199 | 3: "WND4_NOT_SUPP_FTYPE", 1200 | 4: "WND4_WRITE_DELEG_NOT_SUPP_FTYPE", 1201 | 5: "WND4_NOT_SUPP_UPGRADE", 1202 | 6: "WND4_NOT_SUPP_DOWNGRADE", 1203 | 7: "WND4_CANCELLED", 1204 | 8: "WND4_IS_DIR", 1205 | } 1206 | # Result flags 1207 | # 1208 | # Client must confirm open 1209 | OPEN4_RESULT_CONFIRM = 0x00000002 1210 | # Type of file locking behavior at the server 1211 | OPEN4_RESULT_LOCKTYPE_POSIX = 0x00000004 1212 | # Server will preserve file if removed while open 1213 | OPEN4_RESULT_PRESERVE_UNLINKED = 0x00000008 1214 | # Server may use CB_NOTIFY_LOCK on locks derived from this open 1215 | OPEN4_RESULT_MAY_NOTIFY_LOCK = 0x00000020 1216 | 1217 | # Enum nfs_secflavor4 1218 | AUTH_NONE = 0 1219 | AUTH_SYS = 1 1220 | RPCSEC_GSS = 6 1221 | 1222 | nfs_secflavor4 = { 1223 | 0: "AUTH_NONE", 1224 | 1: "AUTH_SYS", 1225 | 6: "RPCSEC_GSS", 1226 | } 1227 | 1228 | # Enum rpc_gss_svc_t 1229 | RPC_GSS_SVC_NONE = 1 1230 | RPC_GSS_SVC_INTEGRITY = 2 1231 | RPC_GSS_SVC_PRIVACY = 3 1232 | 1233 | rpc_gss_svc_t = { 1234 | 1: "RPC_GSS_SVC_NONE", 1235 | 2: "RPC_GSS_SVC_INTEGRITY", 1236 | 3: "RPC_GSS_SVC_PRIVACY", 1237 | } 1238 | 1239 | # Enum channel_dir_from_client4 1240 | CDFC4_FORE = 0x1 1241 | CDFC4_BACK = 0x2 1242 | CDFC4_FORE_OR_BOTH = 0x3 1243 | CDFC4_BACK_OR_BOTH = 0x7 1244 | 1245 | channel_dir_from_client4 = { 1246 | 0x1: "CDFC4_FORE", 1247 | 0x2: "CDFC4_BACK", 1248 | 0x3: "CDFC4_FORE_OR_BOTH", 1249 | 0x7: "CDFC4_BACK_OR_BOTH", 1250 | } 1251 | 1252 | # Enum channel_dir_from_server4 1253 | CDFS4_FORE = 0x1 1254 | CDFS4_BACK = 0x2 1255 | CDFS4_BOTH = 0x3 1256 | 1257 | channel_dir_from_server4 = { 1258 | 0x1: "CDFS4_FORE", 1259 | 0x2: "CDFS4_BACK", 1260 | 0x3: "CDFS4_BOTH", 1261 | } 1262 | 1263 | # EXCHANGE_ID: Instantiate Client ID 1264 | # ====================================================================== 1265 | EXCHGID4_FLAG_SUPP_MOVED_REFER = 0x00000001 1266 | EXCHGID4_FLAG_SUPP_MOVED_MIGR = 0x00000002 1267 | EXCHGID4_FLAG_SUPP_FENCE_OPS = 0x00000004 # New to NFSv4.2 1268 | EXCHGID4_FLAG_BIND_PRINC_STATEID = 0x00000100 1269 | EXCHGID4_FLAG_USE_NON_PNFS = 0x00010000 1270 | EXCHGID4_FLAG_USE_PNFS_MDS = 0x00020000 1271 | EXCHGID4_FLAG_USE_PNFS_DS = 0x00040000 1272 | EXCHGID4_FLAG_MASK_PNFS = 0x00070000 1273 | EXCHGID4_FLAG_UPD_CONFIRMED_REC_A = 0x40000000 1274 | EXCHGID4_FLAG_CONFIRMED_R = 0x80000000 1275 | 1276 | # Enum state_protect_how4 1277 | SP4_NONE = 0 1278 | SP4_MACH_CRED = 1 1279 | SP4_SSV = 2 1280 | 1281 | state_protect_how4 = { 1282 | 0: "SP4_NONE", 1283 | 1: "SP4_MACH_CRED", 1284 | 2: "SP4_SSV", 1285 | } 1286 | 1287 | CREATE_SESSION4_FLAG_PERSIST = 0x00000001 1288 | CREATE_SESSION4_FLAG_CONN_BACK_CHAN = 0x00000002 1289 | CREATE_SESSION4_FLAG_CONN_RDMA = 0x00000004 1290 | 1291 | # Enum gddrnf4_status 1292 | GDD4_OK = 0 1293 | GDD4_UNAVAIL = 1 1294 | 1295 | gddrnf4_status = { 1296 | 0: "GDD4_OK", 1297 | 1: "GDD4_UNAVAIL", 1298 | } 1299 | 1300 | # Enum secinfo_style4 1301 | SECINFO_STYLE4_CURRENT_FH = 0 1302 | SECINFO_STYLE4_PARENT = 1 1303 | 1304 | secinfo_style4 = { 1305 | 0: "SECINFO_STYLE4_CURRENT_FH", 1306 | 1: "SECINFO_STYLE4_PARENT", 1307 | } 1308 | 1309 | SEQ4_STATUS_CB_PATH_DOWN = 0x00000001 1310 | SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING = 0x00000002 1311 | SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED = 0x00000004 1312 | SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED = 0x00000008 1313 | SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED = 0x00000010 1314 | SEQ4_STATUS_ADMIN_STATE_REVOKED = 0x00000020 1315 | SEQ4_STATUS_RECALLABLE_STATE_REVOKED = 0x00000040 1316 | SEQ4_STATUS_LEASE_MOVED = 0x00000080 1317 | SEQ4_STATUS_RESTART_RECLAIM_NEEDED = 0x00000100 1318 | SEQ4_STATUS_CB_PATH_DOWN_SESSION = 0x00000200 1319 | SEQ4_STATUS_BACKCHANNEL_FAULT = 0x00000400 1320 | SEQ4_STATUS_DEVID_CHANGED = 0x00000800 1321 | SEQ4_STATUS_DEVID_DELETED = 0x00001000 1322 | 1323 | # Enum IO_ADVISE_type4 1324 | IO_ADVISE4_NORMAL = 0 1325 | IO_ADVISE4_SEQUENTIAL = 1 1326 | IO_ADVISE4_SEQUENTIAL_BACKWARDS = 2 1327 | IO_ADVISE4_RANDOM = 3 1328 | IO_ADVISE4_WILLNEED = 4 1329 | IO_ADVISE4_WILLNEED_OPPORTUNISTIC = 5 1330 | IO_ADVISE4_DONTNEED = 6 1331 | IO_ADVISE4_NOREUSE = 7 1332 | IO_ADVISE4_READ = 8 1333 | IO_ADVISE4_WRITE = 9 1334 | IO_ADVISE4_INIT_PROXIMITY = 10 1335 | 1336 | IO_ADVISE_type4 = { 1337 | 0: "IO_ADVISE4_NORMAL", 1338 | 1: "IO_ADVISE4_SEQUENTIAL", 1339 | 2: "IO_ADVISE4_SEQUENTIAL_BACKWARDS", 1340 | 3: "IO_ADVISE4_RANDOM", 1341 | 4: "IO_ADVISE4_WILLNEED", 1342 | 5: "IO_ADVISE4_WILLNEED_OPPORTUNISTIC", 1343 | 6: "IO_ADVISE4_DONTNEED", 1344 | 7: "IO_ADVISE4_NOREUSE", 1345 | 8: "IO_ADVISE4_READ", 1346 | 9: "IO_ADVISE4_WRITE", 1347 | 10: "IO_ADVISE4_INIT_PROXIMITY", 1348 | } 1349 | 1350 | # Enum data_content4 1351 | NFS4_CONTENT_DATA = 0 1352 | NFS4_CONTENT_HOLE = 1 1353 | 1354 | data_content4 = { 1355 | 0: "NFS4_CONTENT_DATA", 1356 | 1: "NFS4_CONTENT_HOLE", 1357 | } 1358 | 1359 | # Enum nfs_cb_opnum4 1360 | OP_CB_GETATTR = 3 1361 | OP_CB_RECALL = 4 1362 | # Callback operations new to NFSv4.1 1363 | OP_CB_LAYOUTRECALL = 5 1364 | OP_CB_NOTIFY = 6 1365 | OP_CB_PUSH_DELEG = 7 1366 | OP_CB_RECALL_ANY = 8 1367 | OP_CB_RECALLABLE_OBJ_AVAIL = 9 1368 | OP_CB_RECALL_SLOT = 10 1369 | OP_CB_SEQUENCE = 11 1370 | OP_CB_WANTS_CANCELLED = 12 1371 | OP_CB_NOTIFY_LOCK = 13 1372 | OP_CB_NOTIFY_DEVICEID = 14 1373 | # Callback operations new to NFSv4.2 1374 | OP_CB_OFFLOAD = 15 1375 | # Illegal callback operation 1376 | OP_CB_ILLEGAL = 10044 1377 | 1378 | nfs_cb_opnum4 = { 1379 | 3: "OP_CB_GETATTR", 1380 | 4: "OP_CB_RECALL", 1381 | 5: "OP_CB_LAYOUTRECALL", 1382 | 6: "OP_CB_NOTIFY", 1383 | 7: "OP_CB_PUSH_DELEG", 1384 | 8: "OP_CB_RECALL_ANY", 1385 | 9: "OP_CB_RECALLABLE_OBJ_AVAIL", 1386 | 10: "OP_CB_RECALL_SLOT", 1387 | 11: "OP_CB_SEQUENCE", 1388 | 12: "OP_CB_WANTS_CANCELLED", 1389 | 13: "OP_CB_NOTIFY_LOCK", 1390 | 14: "OP_CB_NOTIFY_DEVICEID", 1391 | 15: "OP_CB_OFFLOAD", 1392 | 10044: "OP_CB_ILLEGAL", 1393 | } 1394 | 1395 | # Enum layoutrecall_type4 1396 | LAYOUTRECALL4_FILE = LAYOUT4_RET_REC_FILE 1397 | LAYOUTRECALL4_FSID = LAYOUT4_RET_REC_FSID 1398 | LAYOUTRECALL4_ALL = LAYOUT4_RET_REC_ALL 1399 | 1400 | layoutrecall_type4 = { 1401 | LAYOUT4_RET_REC_FILE : "LAYOUTRECALL4_FILE", 1402 | LAYOUT4_RET_REC_FSID : "LAYOUTRECALL4_FSID", 1403 | LAYOUT4_RET_REC_ALL : "LAYOUTRECALL4_ALL", 1404 | } 1405 | 1406 | # Enum notify_type4 1407 | NOTIFY4_CHANGE_CHILD_ATTRS = 0 1408 | NOTIFY4_CHANGE_DIR_ATTRS = 1 1409 | NOTIFY4_REMOVE_ENTRY = 2 1410 | NOTIFY4_ADD_ENTRY = 3 1411 | NOTIFY4_RENAME_ENTRY = 4 1412 | NOTIFY4_CHANGE_COOKIE_VERIFIER = 5 1413 | 1414 | notify_type4 = { 1415 | 0: "NOTIFY4_CHANGE_CHILD_ATTRS", 1416 | 1: "NOTIFY4_CHANGE_DIR_ATTRS", 1417 | 2: "NOTIFY4_REMOVE_ENTRY", 1418 | 3: "NOTIFY4_ADD_ENTRY", 1419 | 4: "NOTIFY4_RENAME_ENTRY", 1420 | 5: "NOTIFY4_CHANGE_COOKIE_VERIFIER", 1421 | } 1422 | 1423 | # CB_RECALL_ANY: Keep Any N Recallable Objects 1424 | # ====================================================================== 1425 | RCA4_TYPE_MASK_RDATA_DLG = 0 1426 | RCA4_TYPE_MASK_WDATA_DLG = 1 1427 | RCA4_TYPE_MASK_DIR_DLG = 2 1428 | RCA4_TYPE_MASK_FILE_LAYOUT = 3 1429 | RCA4_TYPE_MASK_BLK_LAYOUT = 4 1430 | RCA4_TYPE_MASK_OBJ_LAYOUT_MIN = 8 1431 | RCA4_TYPE_MASK_OBJ_LAYOUT_MAX = 9 1432 | RCA4_TYPE_MASK_OTHER_LAYOUT_MIN = 12 1433 | RCA4_TYPE_MASK_OTHER_LAYOUT_MAX = 15 1434 | 1435 | # Enum notify_deviceid_type4 1436 | NOTIFY_DEVICEID4_CHANGE = 1 1437 | NOTIFY_DEVICEID4_DELETE = 2 1438 | 1439 | notify_deviceid_type4 = { 1440 | 1: "NOTIFY_DEVICEID4_CHANGE", 1441 | 2: "NOTIFY_DEVICEID4_DELETE", 1442 | } 1443 | -------------------------------------------------------------------------------- /pyNfsClient/mount.py: -------------------------------------------------------------------------------- 1 | import struct 2 | import logging 3 | from .rpc import RPC 4 | from .pack import nfs_pro_v3Unpacker 5 | from .const import MOUNT_PROGRAM, MOUNT_V3, MNT3_OK, MOUNTSTAT3, MNT3ERR_NOTSUPP 6 | 7 | log = logging.getLogger(__package__) 8 | 9 | 10 | class MountAccessError(Exception): 11 | pass 12 | 13 | 14 | class Mount(RPC): 15 | program = MOUNT_PROGRAM 16 | program_version = MOUNT_V3 17 | 18 | def __init__(self, host, port, timeout, auth): 19 | super(Mount, self).__init__(host=host, port=port, timeout=timeout) 20 | self.path = None 21 | self.auth = auth 22 | 23 | def null(self, auth=None): 24 | log.debug("Mount NULL on %s" % self.host) 25 | super(Mount, self).request(self.program, self.program_version, 0, auth=auth if auth else self.auth) 26 | return {"status": MNT3_OK, "message": MOUNTSTAT3[MNT3_OK]} 27 | 28 | def mnt(self, path, auth=None): 29 | data = struct.pack('!L', len(path)) 30 | data += path.encode() 31 | data += b'\x00'*((4-len(path) % 4) % 4) 32 | 33 | log.debug("Do mount on %s" % path) 34 | data = super(Mount, self).request(self.program, self.program_version, 1, data=data, 35 | auth=auth if auth else self.auth) 36 | 37 | unpacker = nfs_pro_v3Unpacker(data) 38 | res = unpacker.unpack_mountres3() 39 | if res["status"] == MNT3_OK: 40 | self.path = path 41 | return res 42 | 43 | def umnt(self, auth=None): 44 | if not self.path: 45 | log.warning("No path mounted, cannot process umount.") 46 | return {"status": MNT3ERR_NOTSUPP, "message": MOUNTSTAT3[MNT3ERR_NOTSUPP]} 47 | data = struct.pack("!L", len(self.path)) 48 | data += self.path.encode() 49 | data += b"\x00" * ((4 - len(self.path) % 4) % 4) 50 | 51 | log.debug("Do umount on %s" % self.path) 52 | super(Mount, self).request(self.program, self.program_version, 3, data=data, auth=auth if auth else self.auth) 53 | 54 | return {"status": MNT3_OK, "message": MOUNTSTAT3[MNT3_OK]} 55 | 56 | def export(self): 57 | log.debug("Get mount export on %s" % self.host) 58 | export = super(Mount, self).request(self.program, self.program_version, 5) 59 | 60 | unpacker = nfs_pro_v3Unpacker(export) 61 | return unpacker.unpack_exports() 62 | -------------------------------------------------------------------------------- /pyNfsClient/nfs3.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from functools import wraps 3 | from .utils import LONG, str_to_bytes 4 | from .rpc import RPC 5 | from .pack import nfs_pro_v3Packer, nfs_pro_v3Unpacker 6 | from .rtypes import (nfs_fh3, set_uint32, set_uint64, sattr3, set_time, diropargs3, setattr3args, create3args, 7 | mkdir3args, symlink3args, commit3args, sattrguard3, access3args, readdir3args, readdirplus3args, 8 | read3args, write3args, createhow3, symlinkdata3, mknod3args, mknoddata3, devicedata3, specdata3, 9 | link3args, rename3args, nfstime3) 10 | from .const import (NFS3_PROCEDURE_NULL, NFS3_PROCEDURE_GETATTR, NFS3_PROCEDURE_SETATTR, NFS3_PROCEDURE_LOOKUP, 11 | NFS3_PROCEDURE_ACCESS, NFS3_PROCEDURE_READLINK, NFS3_PROCEDURE_READ, NFS3_PROCEDURE_WRITE, 12 | NFS3_PROCEDURE_CREATE, NFS3_PROCEDURE_MKDIR, NFS3_PROCEDURE_SYMLINK, NFS3_PROCEDURE_MKNOD, 13 | NFS3_PROCEDURE_REMOVE, NFS3_PROCEDURE_RMDIR, NFS3_PROCEDURE_RENAME, NFS3_PROCEDURE_LINK, 14 | NFS3_PROCEDURE_READDIR, NFS3_PROCEDURE_READDIRPLUS, NFS3_PROCEDURE_FSSTAT, NFS3_PROCEDURE_FSINFO, 15 | NFS3_PROCEDURE_PATHCONF, NFS3_PROCEDURE_COMMIT, NFS_PROGRAM, NFS_V3, NF3BLK, NF3CHR, NF3FIFO, 16 | NF3SOCK, time_how, DONT_CHANGE, SET_TO_CLIENT_TIME, SET_TO_SERVER_TIME) 17 | 18 | logger = logging.getLogger(__package__) 19 | 20 | 21 | class NFSAccessError(Exception): 22 | pass 23 | 24 | 25 | def fh_check(function): 26 | @wraps(function) 27 | def check_fh(*args, **kwargs): 28 | logger.debug("Checking if first argument is bytes type as file/directory handler for [%s]" % function.__name__) 29 | fh = None 30 | if len(args) > 1: 31 | fh = args[1] 32 | else: 33 | for k in kwargs: 34 | if k.endswith("_handle"): 35 | fh = kwargs.get(k) 36 | break 37 | if fh and not isinstance(fh, bytes): 38 | raise TypeError("file/directory should be bytes") 39 | else: 40 | return function(*args, **kwargs) 41 | return check_fh 42 | 43 | 44 | class NFSv3(RPC): 45 | def __init__(self, host, port, timeout, auth): 46 | super(NFSv3, self).__init__(host=host, port=port, timeout=timeout) 47 | self.auth = auth 48 | 49 | def nfs_request(self, procedure, args, auth): 50 | return super(NFSv3, self).request(NFS_PROGRAM, NFS_V3, procedure, data=args, auth=auth) 51 | 52 | def null(self): 53 | logger.debug("NFSv3 procedure %d: NULL on %s" % (NFS3_PROCEDURE_NULL, self.host)) 54 | super(NFSv3, self).request(NFS_PROGRAM, NFS_V3, NFS3_PROCEDURE_NULL) 55 | 56 | return {"status": 0, "resok": None} 57 | 58 | @classmethod 59 | def get_sattr3(cls, mode=None, uid=None, gid=None, size=None, atime_flag=None, atime_s=0, atime_ns=0, 60 | mtime_flag=None, mtime_s=0, mtime_ns=0): 61 | if atime_flag not in time_how: 62 | raise ValueError("atime flag must be one of %s" % time_how.keys()) 63 | 64 | if mtime_flag not in time_how: 65 | raise ValueError("mtime flag must be one of %s" % time_how.keys()) 66 | 67 | attrs = sattr3(mode=set_uint32(True, int(mode)) if mode is not None else set_uint32(False), 68 | uid=set_uint32(True, int(uid)) if uid is not None else set_uint32(False), 69 | gid=set_uint32(True, int(gid)) if gid is not None else set_uint32(False), 70 | size=set_uint64(True, LONG(size)) if size is not None else set_uint64(False), 71 | atime=set_time(SET_TO_CLIENT_TIME, nfstime3(int(atime_s), int(atime_ns))) 72 | if atime_flag == SET_TO_CLIENT_TIME else set_time(atime_flag), 73 | mtime=set_time(SET_TO_CLIENT_TIME, nfstime3(int(mtime_s), int(mtime_ns))) 74 | if mtime_flag == SET_TO_CLIENT_TIME else set_time(mtime_flag)) 75 | return attrs 76 | 77 | @fh_check 78 | def getattr(self, file_handle, auth=None): 79 | packer = nfs_pro_v3Packer() 80 | packer.pack_fhandle3(file_handle) 81 | 82 | logger.debug("NFSv3 procedure %d: GETATTR on %s" % (NFS3_PROCEDURE_GETATTR, self.host)) 83 | data = self.nfs_request(NFS3_PROCEDURE_GETATTR, packer.get_buffer(), auth if auth else self.auth) 84 | 85 | unpacker = nfs_pro_v3Unpacker(data) 86 | return unpacker.unpack_getattr3res() 87 | 88 | @fh_check 89 | def setattr(self, file_handle, mode=None, uid=None, gid=None, size=None, 90 | atime_flag=SET_TO_SERVER_TIME, atime_s=None, atime_us=None, 91 | mtime_flag=SET_TO_SERVER_TIME, mtime_s=None, mtime_us=None, 92 | check=False, obj_ctime=None, auth=None): 93 | packer = nfs_pro_v3Packer() 94 | attrs = self.get_sattr3(mode, uid, gid, size, atime_flag, atime_s, atime_us, mtime_flag, mtime_s, mtime_us) 95 | packer.pack_setattr3args(setattr3args(object=nfs_fh3(file_handle), 96 | new_attributes=attrs, 97 | guard=sattrguard3(check=check, ctime=obj_ctime))) 98 | 99 | logger.debug("NFSv3 procedure %d: GETATTR on %s" % (NFS3_PROCEDURE_SETATTR, self.host)) 100 | data = self.nfs_request(NFS3_PROCEDURE_SETATTR, packer.get_buffer(), auth if auth else self.auth) 101 | 102 | unpacker = nfs_pro_v3Unpacker(data) 103 | return unpacker.unpack_setattr3res() 104 | 105 | @fh_check 106 | def lookup(self, dir_handle, file_folder, auth=None): 107 | packer = nfs_pro_v3Packer() 108 | packer.pack_diropargs3(diropargs3(dir=nfs_fh3(dir_handle), name=str_to_bytes(file_folder))) 109 | 110 | logger.debug("NFSv3 procedure %d: LOOKUP on %s" % (NFS3_PROCEDURE_LOOKUP, self.host)) 111 | data = self.nfs_request(NFS3_PROCEDURE_LOOKUP, packer.get_buffer(), auth if auth else self.auth) 112 | 113 | unpacker = nfs_pro_v3Unpacker(data) 114 | return unpacker.unpack_lookup3res(data_format='json') 115 | 116 | @fh_check 117 | def access(self, file_handle, access_option, auth=None): 118 | packer = nfs_pro_v3Packer() 119 | packer.pack_access3args(access3args(object=nfs_fh3(file_handle), access=access_option)) 120 | 121 | logger.debug("NFSv3 procedure %d: ACCESS on %s" % (NFS3_PROCEDURE_ACCESS, self.host)) 122 | data = self.nfs_request(NFS3_PROCEDURE_ACCESS, packer.get_buffer(), auth if auth else self.auth) 123 | 124 | unpacker = nfs_pro_v3Unpacker(data) 125 | return unpacker.unpack_access3res() 126 | 127 | @fh_check 128 | def readlink(self, file_handle, auth=None): 129 | packer = nfs_pro_v3Packer() 130 | packer.pack_fhandle3(file_handle) 131 | 132 | logger.debug("NFSv3 procedure %d: READLINK on %s" % (NFS3_PROCEDURE_READLINK, self.host)) 133 | data = self.nfs_request(NFS3_PROCEDURE_READLINK, packer.get_buffer(), auth if auth else self.auth) 134 | 135 | unpacker = nfs_pro_v3Unpacker(data) 136 | return unpacker.unpack_readlink3res() 137 | 138 | @fh_check 139 | def read(self, file_handle, offset=0, chunk_count=1024 * 1024, auth=None): 140 | packer = nfs_pro_v3Packer() 141 | packer.pack_read3args(read3args(file=nfs_fh3(file_handle), offset=offset, count=chunk_count)) 142 | 143 | logger.debug("NFSv3 procedure %d: READ on %s" % (NFS3_PROCEDURE_READ, self.host)) 144 | data = self.nfs_request(NFS3_PROCEDURE_READ, packer.get_buffer(), auth if auth else self.auth) 145 | 146 | unpacker = nfs_pro_v3Unpacker(data) 147 | return unpacker.unpack_read3res() 148 | 149 | @fh_check 150 | def write(self, file_handle, offset, count, content, stable_how, auth=None): 151 | packer = nfs_pro_v3Packer() 152 | packer.pack_write3args(write3args(file=nfs_fh3(file_handle), 153 | offset=offset, 154 | count=count, 155 | stable=stable_how, 156 | data=str_to_bytes(content))) 157 | 158 | logger.debug("NFSv3 procedure %d: WRITE on %s" % (NFS3_PROCEDURE_WRITE, self.host)) 159 | res = self.nfs_request(NFS3_PROCEDURE_WRITE, packer.get_buffer(), auth if auth else self.auth) 160 | 161 | unpacker = nfs_pro_v3Unpacker(res) 162 | return unpacker.unpack_write3res() 163 | 164 | @fh_check 165 | def create(self, dir_handle, file_name, create_mode, mode=None, uid=None, gid=None, size=None, 166 | atime_flag=SET_TO_SERVER_TIME, atime_s=None, atime_us=None, 167 | mtime_flag=SET_TO_SERVER_TIME, mtime_s=None, mtime_us=None, 168 | verf='0', auth=None): 169 | packer = nfs_pro_v3Packer() 170 | attrs = self.get_sattr3(mode, uid, gid, size, atime_flag, atime_s, atime_us, mtime_flag, mtime_s, mtime_us) 171 | packer.pack_create3args(create3args(where=diropargs3(dir=nfs_fh3(dir_handle), name=str_to_bytes(file_name)), 172 | how=createhow3(mode=create_mode, obj_attributes=attrs, verf=verf))) 173 | 174 | logger.debug("NFSv3 procedure %d: CREATE on %s" % (NFS3_PROCEDURE_CREATE, self.host)) 175 | data = self.nfs_request(NFS3_PROCEDURE_CREATE, packer.get_buffer(), auth if auth else self.auth) 176 | 177 | unpacker = nfs_pro_v3Unpacker(data) 178 | return unpacker.unpack_create3res() 179 | 180 | @fh_check 181 | def mkdir(self, dir_handle, dir_name, mode=None, uid=None, gid=None, 182 | atime_flag=SET_TO_SERVER_TIME, atime_s=None, atime_us=None, 183 | mtime_flag=SET_TO_SERVER_TIME, mtime_s=None, mtime_us=None, 184 | auth=None): 185 | packer = nfs_pro_v3Packer() 186 | attrs = self.get_sattr3(mode, uid, gid, None, atime_flag, atime_s, atime_us, mtime_flag, mtime_s, mtime_us) 187 | packer.pack_mkdir3args(mkdir3args(where=diropargs3(dir=nfs_fh3(dir_handle), name=str_to_bytes(dir_name)), 188 | attributes=attrs)) 189 | 190 | logger.debug("NFSv3 procedure %d: MKDIR on %s" % (NFS3_PROCEDURE_MKDIR, self.host)) 191 | res = self.nfs_request(NFS3_PROCEDURE_MKDIR, packer.get_buffer(), auth if auth else self.auth) 192 | 193 | unpacker = nfs_pro_v3Unpacker(res) 194 | return unpacker.unpack_mkdir3res() 195 | 196 | @fh_check 197 | def symlink(self, dir_handle, link_name, link_to_path, auth=None): 198 | packer = nfs_pro_v3Packer() 199 | attrs = self.get_sattr3(mode=None, size=None, uid=None, gid=None, atime_flag=DONT_CHANGE, mtime_flag=DONT_CHANGE) 200 | packer.pack_symlink3args(symlink3args(where=diropargs3(dir=nfs_fh3(dir_handle), 201 | name=str_to_bytes(link_name)), 202 | symlink=symlinkdata3(symlink_attributes=attrs, 203 | symlink_data=str_to_bytes(link_to_path)))) 204 | 205 | logger.debug("NFSv3 procedure %d: SYMLINK on %s" % (NFS3_PROCEDURE_SYMLINK, self.host)) 206 | res = self.nfs_request(NFS3_PROCEDURE_SYMLINK, packer.get_buffer(), auth if auth else self.auth) 207 | 208 | unpacker = nfs_pro_v3Unpacker(res) 209 | return unpacker.unpack_symlink3res() 210 | 211 | @fh_check 212 | def mknod(self, dir_handle, file_name, ftype, 213 | mode=None, uid=None, gid=None, 214 | atime_flag=SET_TO_SERVER_TIME, atime_s=None, atime_us=None, 215 | mtime_flag=SET_TO_SERVER_TIME, mtime_s=None, mtime_us=None, 216 | spec_major=0, spec_minor=0, auth=None): 217 | packer = nfs_pro_v3Packer() 218 | attrs = self.get_sattr3(mode, uid, gid, None, atime_flag, atime_s, atime_us, mtime_flag, mtime_s, mtime_us) 219 | if ftype in (NF3CHR, NF3BLK): 220 | spec = specdata3(major=spec_major, minor=spec_minor) 221 | what = mknoddata3(type=ftype, device=devicedata3(dev_attributes=attrs, spec=spec)) 222 | elif ftype in (NF3SOCK, NF3FIFO): 223 | what = mknoddata3(type=ftype, pipe_attributes=attrs) 224 | else: 225 | raise ValueError("ftype must be one of [%d, %d, %d, %d]" % (NF3CHR, NF3BLK, NF3SOCK, NF3FIFO)) 226 | packer.pack_mknod3args(mknod3args(where=diropargs3(dir=nfs_fh3(dir_handle), 227 | name=str_to_bytes(file_name)), 228 | what=what)) 229 | 230 | logger.debug("NFSv3 procedure %d: MKNOD on %s" % (NFS3_PROCEDURE_MKNOD, self.host)) 231 | res = self.nfs_request(NFS3_PROCEDURE_MKNOD, packer.get_buffer(), auth if auth else self.auth) 232 | 233 | unpacker = nfs_pro_v3Unpacker(res) 234 | return unpacker.unpack_mknod3res() 235 | 236 | @fh_check 237 | def remove(self, dir_handle, file_name, auth=None): 238 | packer = nfs_pro_v3Packer() 239 | packer.pack_diropargs3(diropargs3(dir=nfs_fh3(dir_handle), name=str_to_bytes(file_name))) 240 | 241 | logger.debug("NFSv3 procedure %d: REMOVE on %s" % (NFS3_PROCEDURE_REMOVE, self.host)) 242 | res = self.nfs_request(NFS3_PROCEDURE_REMOVE, packer.get_buffer(), auth if auth else self.auth) 243 | 244 | unpacker = nfs_pro_v3Unpacker(res) 245 | return unpacker.unpack_remove3res() 246 | 247 | @fh_check 248 | def rmdir(self, dir_handle, dir_name, auth=None): 249 | packer = nfs_pro_v3Packer() 250 | packer.pack_diropargs3(diropargs3(dir=nfs_fh3(dir_handle), name=str_to_bytes(dir_name))) 251 | 252 | logger.debug("NFSv3 procedure %d: RMDIR on %s" % (NFS3_PROCEDURE_RMDIR, self.host)) 253 | res = self.nfs_request(NFS3_PROCEDURE_RMDIR, packer.get_buffer(), auth if auth else self.auth) 254 | 255 | unpacker = nfs_pro_v3Unpacker(res) 256 | return unpacker.unpack_rmdir3res() 257 | 258 | @fh_check 259 | def rename(self, dir_handle_from, from_name, dir_handle_to, to_name, auth=None): 260 | if not isinstance(dir_handle_to, bytes): 261 | raise TypeError("file handle should be bytes") 262 | 263 | packer = nfs_pro_v3Packer() 264 | packer.pack_rename3args(rename3args(from_v=diropargs3(dir=nfs_fh3(dir_handle_from), 265 | name=str_to_bytes(from_name)), 266 | to=diropargs3(dir=nfs_fh3(dir_handle_to), 267 | name=str_to_bytes(to_name)))) 268 | 269 | logger.debug("NFSv3 procedure %d: RENAME on %s" % (NFS3_PROCEDURE_RENAME, self.host)) 270 | res = self.nfs_request(NFS3_PROCEDURE_RENAME, packer.get_buffer(), auth if auth else self.auth) 271 | 272 | unpacker = nfs_pro_v3Unpacker(res) 273 | return unpacker.unpack_rename3res() 274 | 275 | @fh_check 276 | def link(self, file_handle, link_to_dir_handle, link_name, auth=None): 277 | packer = nfs_pro_v3Packer() 278 | packer.pack_link3args(link3args(file=nfs_fh3(file_handle), 279 | link=diropargs3(dir=nfs_fh3(link_to_dir_handle), name=str_to_bytes(link_name)))) 280 | 281 | logger.debug("NFSv3 procedure %d: LINK on %s" % (NFS3_PROCEDURE_LINK, self.host)) 282 | res = self.nfs_request(NFS3_PROCEDURE_LINK, packer.get_buffer(), auth if auth else self.auth) 283 | 284 | unpacker = nfs_pro_v3Unpacker(res) 285 | return unpacker.unpack_link3res() 286 | 287 | @fh_check 288 | def readdir(self, dir_handle, cookie=0, cookie_verf='0', count=4096, auth=None): 289 | packer = nfs_pro_v3Packer() 290 | packer.pack_readdir3args(readdir3args(dir=nfs_fh3(dir_handle), 291 | cookie=cookie, 292 | cookieverf=str_to_bytes(cookie_verf), 293 | count=count)) 294 | 295 | logger.debug("NFSv3 procedure %d: READDIR on %s" % (NFS3_PROCEDURE_READDIR, self.host)) 296 | res = self.nfs_request(NFS3_PROCEDURE_READDIR, packer.get_buffer(), auth if auth else self.auth) 297 | 298 | unpacker = nfs_pro_v3Unpacker(res) 299 | return unpacker.unpack_readdir3res() 300 | 301 | @fh_check 302 | def readdirplus(self, dir_handle, cookie=0, cookie_verf='0', dircount=4096, maxcount=32768, auth=None): 303 | packer = nfs_pro_v3Packer() 304 | packer.pack_readdirplus3args(readdirplus3args(dir=nfs_fh3(dir_handle), 305 | cookie=cookie, 306 | cookieverf=str_to_bytes(cookie_verf), 307 | dircount=dircount, 308 | maxcount=maxcount)) 309 | 310 | logger.debug("NFSv3 procedure %d: READDIRPLUS on %s" % (NFS3_PROCEDURE_READDIRPLUS, self.host)) 311 | res = self.nfs_request(NFS3_PROCEDURE_READDIRPLUS, packer.get_buffer(), auth if auth else self.auth) 312 | 313 | unpacker = nfs_pro_v3Unpacker(res) 314 | return unpacker.unpack_readdirplus3res() 315 | 316 | @fh_check 317 | def fsstat(self, file_handle, auth=None): 318 | packer = nfs_pro_v3Packer() 319 | packer.pack_fhandle3(file_handle) 320 | 321 | logger.debug("NFSv3 procedure %d: FSSTAT on %s" % (NFS3_PROCEDURE_FSSTAT, self.host)) 322 | data = self.nfs_request(NFS3_PROCEDURE_FSSTAT, packer.get_buffer(), auth if auth else self.auth) 323 | 324 | unpacker = nfs_pro_v3Unpacker(data) 325 | return unpacker.unpack_fsstat3res() 326 | 327 | @fh_check 328 | def fsinfo(self, file_handle, auth=None): 329 | packer = nfs_pro_v3Packer() 330 | packer.pack_fhandle3(file_handle) 331 | 332 | logger.debug("NFSv3 procedure %d: FSINFO on %s" % (NFS3_PROCEDURE_FSINFO, self.host)) 333 | data = self.nfs_request(NFS3_PROCEDURE_FSINFO, packer.get_buffer(), auth if auth else self.auth) 334 | 335 | unpacker = nfs_pro_v3Unpacker(data) 336 | return unpacker.unpack_fsinfo3res() 337 | 338 | @fh_check 339 | def pathconf(self, file_handle, auth=None): 340 | packer = nfs_pro_v3Packer() 341 | packer.pack_fhandle3(file_handle) 342 | 343 | logger.debug("NFSv3 procedure %d: PATHCONF on %s" % (NFS3_PROCEDURE_PATHCONF, self.host)) 344 | data = self.nfs_request(NFS3_PROCEDURE_PATHCONF, packer.get_buffer(), auth if auth else self.auth) 345 | 346 | unpacker = nfs_pro_v3Unpacker(data) 347 | return unpacker.unpack_pathconf3res() 348 | 349 | @fh_check 350 | def commit(self, file_handle, count=0, offset=0, auth=None): 351 | packer = nfs_pro_v3Packer() 352 | packer.pack_commit3args(commit3args(file=nfs_fh3(file_handle), offset=offset, count=count)) 353 | 354 | logger.debug("NFSv3 procedure %d: COMMIT on %s" % (NFS3_PROCEDURE_COMMIT, self.host)) 355 | res = self.nfs_request(NFS3_PROCEDURE_COMMIT, packer.get_buffer(), auth if auth else self.auth) 356 | 357 | unpacker = nfs_pro_v3Unpacker(res) 358 | return unpacker.unpack_commit3res() 359 | -------------------------------------------------------------------------------- /pyNfsClient/pack.py: -------------------------------------------------------------------------------- 1 | import struct 2 | from xdrlib import Packer, Unpacker, ConversionError 3 | from xdrlib import Error as XDRError 4 | from . import const 5 | from . import rtypes as types 6 | 7 | 8 | class nullclass(object): 9 | pass 10 | 11 | 12 | class nfs_pro_v3Packer(Packer): 13 | pack_hyper = Packer.pack_hyper 14 | pack_string = Packer.pack_string 15 | pack_int = Packer.pack_int 16 | pack_float = Packer.pack_float 17 | pack_uint = Packer.pack_uint 18 | pack_opaque = Packer.pack_opaque 19 | pack_double = Packer.pack_double 20 | pack_unsigned = Packer.pack_uint 21 | pack_quadruple = Packer.pack_double 22 | pack_uhyper = Packer.pack_uhyper 23 | pack_bool = Packer.pack_bool 24 | pack_uint32 = pack_uint64 = pack_uint 25 | 26 | def pack_uint64(self, x): 27 | try: 28 | self._Packer__buf.write(struct.pack('>Q', x)) 29 | except struct.error as e: 30 | raise ConversionError(e.args[0]) 31 | 32 | def pack_filename3(self, data): 33 | self.pack_string(data) 34 | 35 | def pack_nfspath3(self, data): 36 | self.pack_string(data) 37 | 38 | def pack_cookieverf3(self, data): 39 | self.pack_fopaque(const.NFS3_COOKIEVERFSIZE, data) 40 | 41 | def pack_createverf3(self, data): 42 | self.pack_fopaque(const.NFS3_CREATEVERFSIZE, data) 43 | 44 | def pack_writeverf3(self, data): 45 | self.pack_fopaque(const.NFS3_WRITEVERFSIZE, data) 46 | 47 | def pack_nfsstat3(self, data): 48 | if data not in [const.NFS3_OK, const.NFS3ERR_PERM, const.NFS3ERR_NOENT, const.NFS3ERR_IO, const.NFS3ERR_NXIO, 49 | const.NFS3ERR_ACCES, const.NFS3ERR_EXIST, const.NFS3ERR_XDEV, const.NFS3ERR_NODEV, 50 | const.NFS3ERR_NOTDIR, const.NFS3ERR_ISDIR, const.NFS3ERR_INVAL, const.NFS3ERR_FBIG, 51 | const.NFS3ERR_NOSPC, const.NFS3ERR_ROFS, const.NFS3ERR_MLINK, const.NFS3ERR_NAMETOOLONG, 52 | const.NFS3ERR_NOTEMPTY, const.NFS3ERR_DQUOT, const.NFS3ERR_STALE, const.NFS3ERR_REMOTE, 53 | const.NFS3ERR_BADHANDLE, const.NFS3ERR_NOT_SYNC, const.NFS3ERR_BAD_COOKIE, 54 | const.NFS3ERR_NOTSUPP, const.NFS3ERR_TOOSMALL, const.NFS3ERR_SERVERFAULT, const.NFS3ERR_BADTYPE, 55 | const.NFS3ERR_JUKEBOX]: 56 | raise XDRError('value=%s not in enum nfsstat3' % data) 57 | self.pack_int(data) 58 | 59 | def pack_ftype3(self, data): 60 | if data not in [const.NF3REG, const.NF3DIR, const.NF3BLK, const.NF3CHR, const.NF3LNK, const.NF3SOCK, 61 | const.NF3FIFO]: 62 | raise XDRError('value=%s not in enum ftype3' % data) 63 | self.pack_int(data) 64 | 65 | def pack_specdata3(self, data): 66 | if data.major is None: 67 | raise TypeError('data.major == None') 68 | self.pack_uint32(data.major) 69 | if data.minor is None: 70 | raise TypeError('data.minor == None') 71 | self.pack_uint32(data.minor) 72 | 73 | def pack_nfs_fh3(self, data): 74 | if data.data is None: 75 | raise TypeError('data.data == None') 76 | if len(data.data) > const.NFS3_FHSIZE: 77 | raise XDRError('array length too long for data.data') 78 | self.pack_opaque(data.data) 79 | 80 | def pack_nfstime3(self, data): 81 | if data.seconds is None: 82 | raise TypeError('data.seconds == None') 83 | self.pack_uint32(data.seconds) 84 | if data.nseconds is None: 85 | raise TypeError('data.nseconds == None') 86 | self.pack_uint32(data.nseconds) 87 | 88 | def pack_fattr3(self, data): 89 | if data.type is None: 90 | raise TypeError('data.type == None') 91 | self.pack_ftype3(data.type) 92 | if data.mode is None: 93 | raise TypeError('data.mode == None') 94 | self.pack_uint32(data.mode) 95 | if data.nlink is None: 96 | raise TypeError('data.nlink == None') 97 | self.pack_uint32(data.nlink) 98 | if data.uid is None: 99 | raise TypeError('data.uid == None') 100 | self.pack_uint32(data.uid) 101 | if data.gid is None: 102 | raise TypeError('data.gid == None') 103 | self.pack_uint32(data.gid) 104 | if data.size is None: 105 | raise TypeError('data.size == None') 106 | self.pack_uint64(data.size) 107 | if data.used is None: 108 | raise TypeError('data.used == None') 109 | self.pack_uint64(data.used) 110 | if data.rdev is None: 111 | raise TypeError('data.rdev == None') 112 | self.pack_specdata3(data.rdev) 113 | if data.fsid is None: 114 | raise TypeError('data.fsid == None') 115 | self.pack_uint64(data.fsid) 116 | if data.fileid is None: 117 | raise TypeError('data.fileid == None') 118 | self.pack_uint64(data.fileid) 119 | if data.atime is None: 120 | raise TypeError('data.atime == None') 121 | self.pack_nfstime3(data.atime) 122 | if data.mtime is None: 123 | raise TypeError('data.mtime == None') 124 | self.pack_nfstime3(data.mtime) 125 | if data.ctime is None: 126 | raise TypeError('data.ctime == None') 127 | self.pack_nfstime3(data.ctime) 128 | 129 | def pack_post_op_attr(self, data): 130 | if data.present is None: 131 | raise TypeError('data.present == None') 132 | self.pack_bool(data.present) 133 | if data.present == const.TRUE: 134 | if data.attributes is None: 135 | raise TypeError('data.attributes == None') 136 | self.pack_fattr3(data.attributes) 137 | elif data.present == const.FALSE: 138 | pass 139 | else: 140 | raise XDRError('bad switch=%s' % data.present) 141 | 142 | def pack_wcc_attr(self, data): 143 | if data.size is None: 144 | raise TypeError('data.size == None') 145 | self.pack_uint64(data.size) 146 | if data.mtime is None: 147 | raise TypeError('data.mtime == None') 148 | self.pack_nfstime3(data.mtime) 149 | if data.ctime is None: 150 | raise TypeError('data.ctime == None') 151 | self.pack_nfstime3(data.ctime) 152 | 153 | def pack_pre_op_attr(self, data): 154 | if data.present is None: 155 | raise TypeError('data.present == None') 156 | self.pack_bool(data.present) 157 | if data.present == const.TRUE: 158 | if data.attributes is None: 159 | raise TypeError('data.attributes == None') 160 | self.pack_wcc_attr(data.attributes) 161 | elif data.present == const.FALSE: 162 | pass 163 | else: 164 | raise XDRError('bad switch=%s' % data.present) 165 | 166 | def pack_wcc_data(self, data): 167 | if data.before is None: 168 | raise TypeError('data.before == None') 169 | self.pack_pre_op_attr(data.before) 170 | if data.after is None: 171 | raise TypeError('data.after == None') 172 | self.pack_post_op_attr(data.after) 173 | 174 | def pack_post_op_fh3(self, data): 175 | if data.present is None: 176 | raise TypeError('data.present == None') 177 | self.pack_bool(data.present) 178 | if data.present == const.TRUE: 179 | if data.handle is None: 180 | raise TypeError('data.handle == None') 181 | self.pack_nfs_fh3(data.handle) 182 | elif data.present == const.FALSE: 183 | pass 184 | else: 185 | raise XDRError('bad switch=%s' % data.present) 186 | 187 | def pack_set_uint32(self, data): 188 | if data.set is None: 189 | raise TypeError('data.set == None') 190 | self.pack_bool(data.set) 191 | if data.set == const.TRUE: 192 | if data.val is None: 193 | raise TypeError('data.val == None') 194 | self.pack_uint32(data.val) 195 | else: 196 | pass 197 | 198 | def pack_set_uint64(self, data): 199 | if data.set is None: 200 | raise TypeError('data.set == None') 201 | self.pack_bool(data.set) 202 | if data.set == const.TRUE: 203 | if data.val is None: 204 | raise TypeError('data.val == None') 205 | self.pack_uint64(data.val) 206 | else: 207 | pass 208 | 209 | def pack_time_how(self, data): 210 | if data not in [const.DONT_CHANGE, const.SET_TO_SERVER_TIME, const.SET_TO_CLIENT_TIME]: 211 | raise XDRError('value=%s not in enum time_how' % data) 212 | self.pack_int(data) 213 | 214 | def pack_set_time(self, data): 215 | if data.set is None: 216 | raise TypeError('data.set == None') 217 | self.pack_time_how(data.set) 218 | if data.set == const.SET_TO_CLIENT_TIME: 219 | if data.time is None: 220 | raise TypeError('data.time == None') 221 | self.pack_nfstime3(data.time) 222 | else: 223 | pass 224 | 225 | def pack_sattr3(self, data): 226 | if data.mode is None: 227 | raise TypeError('data.mode == None') 228 | self.pack_set_uint32(data.mode) 229 | if data.uid is None: 230 | raise TypeError('data.uid == None') 231 | self.pack_set_uint32(data.uid) 232 | if data.gid is None: 233 | raise TypeError('data.gid == None') 234 | self.pack_set_uint32(data.gid) 235 | if data.size is None: 236 | raise TypeError('data.size == None') 237 | self.pack_set_uint64(data.size) 238 | if data.atime is None: 239 | raise TypeError('data.atime == None') 240 | self.pack_set_time(data.atime) 241 | if data.mtime is None: 242 | raise TypeError('data.mtime == None') 243 | self.pack_set_time(data.mtime) 244 | 245 | def pack_diropargs3(self, data): 246 | if data.dir is None: 247 | raise TypeError('data.dir == None') 248 | self.pack_nfs_fh3(data.dir) 249 | if data.name is None: 250 | raise TypeError('data.name == None') 251 | self.pack_filename3(data.name) 252 | 253 | def pack_diropres3ok(self, data): 254 | if data.obj is None: 255 | raise TypeError('data.obj == None') 256 | self.pack_post_op_fh3(data.obj) 257 | if data.obj_attributes is None: 258 | raise TypeError('data.obj_attributes == None') 259 | self.pack_post_op_attr(data.obj_attributes) 260 | if data.dir_wcc is None: 261 | raise TypeError('data.dir_wcc == None') 262 | self.pack_wcc_data(data.dir_wcc) 263 | 264 | def pack_diropres3(self, data): 265 | if data.status is None: 266 | raise TypeError('data.status == None') 267 | self.pack_nfsstat3(data.status) 268 | if data.status == const.NFS3_OK: 269 | if data.resok is None: 270 | raise TypeError('data.resok == None') 271 | self.pack_diropres3ok(data.resok) 272 | else: 273 | if data.resfail is None: 274 | raise TypeError('data.resfail == None') 275 | self.pack_wcc_data(data.resfail) 276 | 277 | def pack_wccstat3(self, data): 278 | if data.status is None: 279 | raise TypeError('data.status == None') 280 | self.pack_nfsstat3(data.status) 281 | if data.status == -1: 282 | pass 283 | else: 284 | if data.wcc is None: 285 | raise TypeError('data.wcc == None') 286 | self.pack_wcc_data(data.wcc) 287 | 288 | def pack_getattr3res(self, data): 289 | if data.status is None: 290 | raise TypeError('data.status == None') 291 | self.pack_nfsstat3(data.status) 292 | if data.status == const.NFS3_OK: 293 | if data.attributes is None: 294 | raise TypeError('data.attributes == None') 295 | self.pack_fattr3(data.attributes) 296 | else: 297 | pass 298 | 299 | def pack_sattrguard3(self, data): 300 | if data.check is None: 301 | raise TypeError('data.check == None') 302 | self.pack_bool(data.check) 303 | if data.check == const.TRUE: 304 | if data.ctime is None: 305 | raise TypeError('data.ctime == None') 306 | self.pack_nfstime3(data.ctime) 307 | elif data.check == const.FALSE: 308 | pass 309 | else: 310 | raise XDRError('bad switch=%s' % data.check) 311 | 312 | def pack_setattr3args(self, data): 313 | if data.object is None: 314 | raise TypeError('data.object == None') 315 | self.pack_nfs_fh3(data.object) 316 | if data.new_attributes is None: 317 | raise TypeError('data.new_attributes == None') 318 | self.pack_sattr3(data.new_attributes) 319 | if data.guard is None: 320 | raise TypeError('data.guard == None') 321 | self.pack_sattrguard3(data.guard) 322 | 323 | def pack_lookup3resok(self, data): 324 | if data.object is None: 325 | raise TypeError('data.object == None') 326 | self.pack_nfs_fh3(data.object) 327 | if data.obj_attributes is None: 328 | raise TypeError('data.obj_attributes == None') 329 | self.pack_post_op_attr(data.obj_attributes) 330 | if data.dir_attributes is None: 331 | raise TypeError('data.dir_attributes == None') 332 | self.pack_post_op_attr(data.dir_attributes) 333 | 334 | def pack_lookup3res(self, data): 335 | if data.status is None: 336 | raise TypeError('data.status == None') 337 | self.pack_nfsstat3(data.status) 338 | if data.status == const.NFS3_OK: 339 | if data.resok is None: 340 | raise TypeError('data.resok == None') 341 | self.pack_lookup3resok(data.resok) 342 | else: 343 | if data.resfail is None: 344 | raise TypeError('data.resfail == None') 345 | self.pack_post_op_attr(data.resfail) 346 | 347 | def pack_access3args(self, data): 348 | if data.object is None: 349 | raise TypeError('data.object == None') 350 | self.pack_nfs_fh3(data.object) 351 | if data.access is None: 352 | raise TypeError('data.access == None') 353 | self.pack_uint32(data.access) 354 | 355 | def pack_access3resok(self, data): 356 | if data.obj_attributes is None: 357 | raise TypeError('data.obj_attributes == None') 358 | self.pack_post_op_attr(data.obj_attributes) 359 | if data.access is None: 360 | raise TypeError('data.access == None') 361 | self.pack_uint32(data.access) 362 | 363 | def pack_access3res(self, data): 364 | if data.status is None: 365 | raise TypeError('data.status == None') 366 | self.pack_nfsstat3(data.status) 367 | if data.status == const.NFS3_OK: 368 | if data.resok is None: 369 | raise TypeError('data.resok == None') 370 | self.pack_access3resok(data.resok) 371 | else: 372 | if data.resfail is None: 373 | raise TypeError('data.resfail == None') 374 | self.pack_post_op_attr(data.resfail) 375 | 376 | def pack_readlink3resok(self, data): 377 | if data.symlink_attributes is None: 378 | raise TypeError('data.symlink_attributes == None') 379 | self.pack_post_op_attr(data.symlink_attributes) 380 | if data.data is None: 381 | raise TypeError('data.data == None') 382 | self.pack_nfspath3(data.data) 383 | 384 | def pack_readlink3res(self, data): 385 | if data.status is None: 386 | raise TypeError('data.status == None') 387 | self.pack_nfsstat3(data.status) 388 | if data.status == const.NFS3_OK: 389 | if data.resok is None: 390 | raise TypeError('data.resok == None') 391 | self.pack_readlink3resok(data.resok) 392 | else: 393 | if data.resfail is None: 394 | raise TypeError('data.resfail == None') 395 | self.pack_post_op_attr(data.resfail) 396 | 397 | def pack_read3args(self, data): 398 | if data.file is None: 399 | raise TypeError('data.file == None') 400 | self.pack_nfs_fh3(data.file) 401 | if data.offset is None: 402 | raise TypeError('data.offset == None') 403 | self.pack_uint64(data.offset) 404 | if data.count is None: 405 | raise TypeError('data.count == None') 406 | self.pack_uint32(data.count) 407 | 408 | def pack_read3resok(self, data): 409 | if data.file_attributes is None: 410 | raise TypeError('data.file_attributes == None') 411 | self.pack_post_op_attr(data.file_attributes) 412 | if data.count is None: 413 | raise TypeError('data.count == None') 414 | self.pack_uint32(data.count) 415 | if data.eof is None: 416 | raise TypeError('data.eof == None') 417 | self.pack_bool(data.eof) 418 | if data.data is None: 419 | raise TypeError('data.data == None') 420 | self.pack_opaque(data.data) 421 | 422 | def pack_read3res(self, data): 423 | if data.status is None: 424 | raise TypeError('data.status == None') 425 | self.pack_nfsstat3(data.status) 426 | if data.status == const.NFS3_OK: 427 | if data.resok is None: 428 | raise TypeError('data.resok == None') 429 | self.pack_read3resok(data.resok) 430 | else: 431 | if data.resfail is None: 432 | raise TypeError('data.resfail == None') 433 | self.pack_post_op_attr(data.resfail) 434 | 435 | def pack_stable_how(self, data): 436 | if data not in [const.UNSTABLE, const.DATA_SYNC, const.FILE_SYNC]: 437 | raise XDRError('value=%s not in enum stable_how' % data) 438 | self.pack_int(data) 439 | 440 | def pack_write3args(self, data): 441 | if data.file is None: 442 | raise TypeError('data.file == None') 443 | self.pack_nfs_fh3(data.file) 444 | if data.offset is None: 445 | raise TypeError('data.offset == None') 446 | self.pack_uint64(data.offset) 447 | if data.count is None: 448 | raise TypeError('data.count == None') 449 | self.pack_uint32(data.count) 450 | if data.stable is None: 451 | raise TypeError('data.stable == None') 452 | self.pack_stable_how(data.stable) 453 | if data.data is None: 454 | raise TypeError('data.data == None') 455 | self.pack_opaque(data.data) 456 | 457 | def pack_write3resok(self, data): 458 | if data.file_wcc is None: 459 | raise TypeError('data.file_wcc == None') 460 | self.pack_wcc_data(data.file_wcc) 461 | if data.count is None: 462 | raise TypeError('data.count == None') 463 | self.pack_uint32(data.count) 464 | if data.committed is None: 465 | raise TypeError('data.committed == None') 466 | self.pack_stable_how(data.committed) 467 | if data.verf is None: 468 | raise TypeError('data.verf == None') 469 | self.pack_writeverf3(data.verf) 470 | 471 | def pack_write3res(self, data): 472 | if data.status is None: 473 | raise TypeError('data.status == None') 474 | self.pack_nfsstat3(data.status) 475 | if data.status == const.NFS3_OK: 476 | if data.resok is None: 477 | raise TypeError('data.resok == None') 478 | self.pack_write3resok(data.resok) 479 | else: 480 | if data.resfail is None: 481 | raise TypeError('data.resfail == None') 482 | self.pack_wcc_data(data.resfail) 483 | 484 | def pack_createmode3(self, data): 485 | if data not in [const.UNCHECKED, const.GUARDED, const.EXCLUSIVE]: 486 | raise XDRError('value=%s not in enum createmode3' % data) 487 | self.pack_int(data) 488 | 489 | def pack_createhow3(self, data): 490 | if data.mode is None: 491 | raise TypeError('data.mode == None') 492 | self.pack_createmode3(data.mode) 493 | if data.mode == const.UNCHECKED or data.mode == const.GUARDED: 494 | if data.obj_attributes is None: 495 | raise TypeError('data.obj_attributes == None') 496 | self.pack_sattr3(data.obj_attributes) 497 | elif data.mode == const.EXCLUSIVE: 498 | if data.verf is None: 499 | raise TypeError('data.verf == None') 500 | self.pack_createverf3(data.verf) 501 | else: 502 | raise XDRError('bad switch=%s' % data.mode) 503 | 504 | def pack_create3args(self, data): 505 | if data.where is None: 506 | raise TypeError('data.where == None') 507 | self.pack_diropargs3(data.where) 508 | if data.how is None: 509 | raise TypeError('data.how == None') 510 | self.pack_createhow3(data.how) 511 | 512 | def pack_mkdir3args(self, data): 513 | if data.where is None: 514 | raise TypeError('data.where == None') 515 | self.pack_diropargs3(data.where) 516 | if data.attributes is None: 517 | raise TypeError('data.attributes == None') 518 | self.pack_sattr3(data.attributes) 519 | 520 | def pack_symlinkdata3(self, data): 521 | if data.symlink_attributes is None: 522 | raise TypeError('data.symlink_attributes == None') 523 | self.pack_sattr3(data.symlink_attributes) 524 | if data.symlink_data is None: 525 | raise TypeError('data.symlink_data == None') 526 | self.pack_nfspath3(data.symlink_data) 527 | 528 | def pack_symlink3args(self, data): 529 | if data.where is None: 530 | raise TypeError('data.where == None') 531 | self.pack_diropargs3(data.where) 532 | if data.symlink is None: 533 | raise TypeError('data.symlink == None') 534 | self.pack_symlinkdata3(data.symlink) 535 | 536 | def pack_devicedata3(self, data): 537 | if data.dev_attributes is None: 538 | raise TypeError('data.dev_attributes == None') 539 | self.pack_sattr3(data.dev_attributes) 540 | if data.spec is None: 541 | raise TypeError('data.spec == None') 542 | self.pack_specdata3(data.spec) 543 | 544 | def pack_mknoddata3(self, data): 545 | if data.type is None: 546 | raise TypeError('data.type == None') 547 | self.pack_ftype3(data.type) 548 | if data.type == const.NF3CHR or data.type == const.NF3BLK: 549 | if data.device is None: 550 | raise TypeError('data.device == None') 551 | self.pack_devicedata3(data.device) 552 | elif data.type == const.NF3SOCK or data.type == const.NF3FIFO: 553 | if data.pipe_attributes is None: 554 | raise TypeError('data.pipe_attributes == None') 555 | self.pack_sattr3(data.pipe_attributes) 556 | else: 557 | pass 558 | 559 | def pack_mknod3args(self, data): 560 | if data.where is None: 561 | raise TypeError('data.where == None') 562 | self.pack_diropargs3(data.where) 563 | if data.what is None: 564 | raise TypeError('data.what == None') 565 | self.pack_mknoddata3(data.what) 566 | 567 | def pack_rename3args(self, data): 568 | if data.from_v is None: 569 | raise TypeError('data.from == None') 570 | self.pack_diropargs3(data.from_v) 571 | if data.to is None: 572 | raise TypeError('data.to == None') 573 | self.pack_diropargs3(data.to) 574 | 575 | def pack_rename3wcc(self, data): 576 | if data.fromdir_wcc is None: 577 | raise TypeError('data.fromdir_wcc == None') 578 | self.pack_wcc_data(data.fromdir_wcc) 579 | if data.todir_wcc is None: 580 | raise TypeError('data.todir_wcc == None') 581 | self.pack_wcc_data(data.todir_wcc) 582 | 583 | def pack_rename3res(self, data): 584 | if data.status is None: 585 | raise TypeError('data.status == None') 586 | self.pack_nfsstat3(data.status) 587 | if data.status == -1: 588 | pass 589 | else: 590 | if data.res is None: 591 | raise TypeError('data.res == None') 592 | self.pack_rename3wcc(data.res) 593 | 594 | def pack_link3args(self, data): 595 | if data.file is None: 596 | raise TypeError('data.file == None') 597 | self.pack_nfs_fh3(data.file) 598 | if data.link is None: 599 | raise TypeError('data.link == None') 600 | self.pack_diropargs3(data.link) 601 | 602 | def pack_link3wcc(self, data): 603 | if data.file_attributes is None: 604 | raise TypeError('data.file_attributes == None') 605 | self.pack_post_op_attr(data.file_attributes) 606 | if data.linkdir_wcc is None: 607 | raise TypeError('data.linkdir_wcc == None') 608 | self.pack_wcc_data(data.linkdir_wcc) 609 | 610 | def pack_link3res(self, data): 611 | if data.status is None: 612 | raise TypeError('data.status == None') 613 | self.pack_nfsstat3(data.status) 614 | if data.status == -1: 615 | pass 616 | else: 617 | if data.res is None: 618 | raise TypeError('data.res == None') 619 | self.pack_link3wcc(data.res) 620 | 621 | def pack_readdir3args(self, data): 622 | if data.dir is None: 623 | raise TypeError('data.dir == None') 624 | self.pack_nfs_fh3(data.dir) 625 | if data.cookie is None: 626 | raise TypeError('data.cookie == None') 627 | self.pack_uint64(data.cookie) 628 | if data.cookieverf is None: 629 | raise TypeError('data.cookieverf == None') 630 | self.pack_cookieverf3(data.cookieverf) 631 | if data.count is None: 632 | raise TypeError('data.count == None') 633 | self.pack_uint32(data.count) 634 | 635 | def pack_entry3(self, data): 636 | if data.fileid is None: 637 | raise TypeError('data.fileid == None') 638 | self.pack_uint64(data.fileid) 639 | if data.name is None: 640 | raise TypeError('data.name == None') 641 | self.pack_filename3(data.name) 642 | if data.cookie is None: 643 | raise TypeError('data.cookie == None') 644 | self.pack_uint64(data.cookie) 645 | if data.nextentry is None: 646 | raise TypeError('data.nextentry == None') 647 | if len(data.nextentry) > 1: 648 | raise XDRError('array length too long for data.nextentry') 649 | self.pack_array(data.nextentry, self.pack_entry3) 650 | 651 | def pack_dirlist3(self, data): 652 | if data.entries is None: 653 | raise TypeError('data.entries == None') 654 | if len(data.entries) > 1: 655 | raise XDRError('array length too long for data.entries') 656 | self.pack_array(data.entries, self.pack_entry3) 657 | if data.eof is None: 658 | raise TypeError('data.eof == None') 659 | self.pack_bool(data.eof) 660 | 661 | def pack_readdir3resok(self, data): 662 | if data.dir_attributes is None: 663 | raise TypeError('data.dir_attributes == None') 664 | self.pack_post_op_attr(data.dir_attributes) 665 | if data.cookieverf is None: 666 | raise TypeError('data.cookieverf == None') 667 | self.pack_cookieverf3(data.cookieverf) 668 | if data.reply is None: 669 | raise TypeError('data.reply == None') 670 | self.pack_dirlist3(data.reply) 671 | 672 | def pack_readdir3res(self, data): 673 | if data.status is None: 674 | raise TypeError('data.status == None') 675 | self.pack_nfsstat3(data.status) 676 | if data.status == const.NFS3_OK: 677 | if data.resok is None: 678 | raise TypeError('data.resok == None') 679 | self.pack_readdir3resok(data.resok) 680 | else: 681 | if data.resfail is None: 682 | raise TypeError('data.resfail == None') 683 | self.pack_post_op_attr(data.resfail) 684 | 685 | def pack_readdirplus3args(self, data): 686 | if data.dir is None: 687 | raise TypeError('data.dir == None') 688 | self.pack_nfs_fh3(data.dir) 689 | if data.cookie is None: 690 | raise TypeError('data.cookie == None') 691 | self.pack_uint64(data.cookie) 692 | if data.cookieverf is None: 693 | raise TypeError('data.cookieverf == None') 694 | self.pack_cookieverf3(data.cookieverf) 695 | if data.dircount is None: 696 | raise TypeError('data.dircount == None') 697 | self.pack_uint32(data.dircount) 698 | if data.maxcount is None: 699 | raise TypeError('data.maxcount == None') 700 | self.pack_uint32(data.maxcount) 701 | 702 | def pack_entryplus3(self, data): 703 | if data.fileid is None: 704 | raise TypeError('data.fileid == None') 705 | self.pack_uint64(data.fileid) 706 | if data.name is None: 707 | raise TypeError('data.name == None') 708 | self.pack_filename3(data.name) 709 | if data.cookie is None: 710 | raise TypeError('data.cookie == None') 711 | self.pack_uint64(data.cookie) 712 | if data.name_attributes is None: 713 | raise TypeError('data.name_attributes == None') 714 | self.pack_post_op_attr(data.name_attributes) 715 | if data.name_handle is None: 716 | raise TypeError('data.name_handle == None') 717 | self.pack_post_op_fh3(data.name_handle) 718 | if data.nextentry is None: 719 | raise TypeError('data.nextentry == None') 720 | if len(data.nextentry) > 1: 721 | raise XDRError('array length too long for data.nextentry') 722 | self.pack_array(data.nextentry, self.pack_entryplus3) 723 | 724 | def pack_dirlistplus3(self, data): 725 | if data.entries is None: 726 | raise TypeError('data.entries == None') 727 | if len(data.entries) > 1: 728 | raise XDRError('array length too long for data.entries') 729 | self.pack_array(data.entries, self.pack_entryplus3) 730 | if data.eof is None: 731 | raise TypeError('data.eof == None') 732 | self.pack_bool(data.eof) 733 | 734 | def pack_readdirplus3resok(self, data): 735 | if data.dir_attributes is None: 736 | raise TypeError('data.dir_attributes == None') 737 | self.pack_post_op_attr(data.dir_attributes) 738 | if data.cookieverf is None: 739 | raise TypeError('data.cookieverf == None') 740 | self.pack_cookieverf3(data.cookieverf) 741 | if data.reply is None: 742 | raise TypeError('data.reply == None') 743 | self.pack_dirlistplus3(data.reply) 744 | 745 | def pack_readdirplus3res(self, data): 746 | if data.status is None: 747 | raise TypeError('data.status == None') 748 | self.pack_nfsstat3(data.status) 749 | if data.status == const.NFS3_OK: 750 | if data.resok is None: 751 | raise TypeError('data.resok == None') 752 | self.pack_readdirplus3resok(data.resok) 753 | else: 754 | if data.resfail is None: 755 | raise TypeError('data.resfail == None') 756 | self.pack_post_op_attr(data.resfail) 757 | 758 | def pack_fsstat3resok(self, data): 759 | if data.obj_attributes is None: 760 | raise TypeError('data.obj_attributes == None') 761 | self.pack_post_op_attr(data.obj_attributes) 762 | if data.tbytes is None: 763 | raise TypeError('data.tbytes == None') 764 | self.pack_uint64(data.tbytes) 765 | if data.fbytes is None: 766 | raise TypeError('data.fbytes == None') 767 | self.pack_uint64(data.fbytes) 768 | if data.abytes is None: 769 | raise TypeError('data.abytes == None') 770 | self.pack_uint64(data.abytes) 771 | if data.tfiles is None: 772 | raise TypeError('data.tfiles == None') 773 | self.pack_uint64(data.tfiles) 774 | if data.ffiles is None: 775 | raise TypeError('data.ffiles == None') 776 | self.pack_uint64(data.ffiles) 777 | if data.afiles is None: 778 | raise TypeError('data.afiles == None') 779 | self.pack_uint64(data.afiles) 780 | if data.invarsec is None: 781 | raise TypeError('data.invarsec == None') 782 | self.pack_uint32(data.invarsec) 783 | 784 | def pack_fsstat3res(self, data): 785 | if data.status is None: 786 | raise TypeError('data.status == None') 787 | self.pack_nfsstat3(data.status) 788 | if data.status == const.NFS3_OK: 789 | if data.resok is None: 790 | raise TypeError('data.resok == None') 791 | self.pack_fsstat3resok(data.resok) 792 | else: 793 | if data.resfail is None: 794 | raise TypeError('data.resfail == None') 795 | self.pack_post_op_attr(data.resfail) 796 | 797 | def pack_fsinfo3resok(self, data): 798 | if data.obj_attributes is None: 799 | raise TypeError('data.obj_attributes == None') 800 | self.pack_post_op_attr(data.obj_attributes) 801 | if data.rtmax is None: 802 | raise TypeError('data.rtmax == None') 803 | self.pack_uint32(data.rtmax) 804 | if data.rtpref is None: 805 | raise TypeError('data.rtpref == None') 806 | self.pack_uint32(data.rtpref) 807 | if data.rtmult is None: 808 | raise TypeError('data.rtmult == None') 809 | self.pack_uint32(data.rtmult) 810 | if data.wtmax is None: 811 | raise TypeError('data.wtmax == None') 812 | self.pack_uint32(data.wtmax) 813 | if data.wtpref is None: 814 | raise TypeError('data.wtpref == None') 815 | self.pack_uint32(data.wtpref) 816 | if data.wtmult is None: 817 | raise TypeError('data.wtmult == None') 818 | self.pack_uint32(data.wtmult) 819 | if data.dtpref is None: 820 | raise TypeError('data.dtpref == None') 821 | self.pack_uint32(data.dtpref) 822 | if data.maxfilesize is None: 823 | raise TypeError('data.maxfilesize == None') 824 | self.pack_uint64(data.maxfilesize) 825 | if data.time_delta is None: 826 | raise TypeError('data.time_delta == None') 827 | self.pack_nfstime3(data.time_delta) 828 | if data.properties is None: 829 | raise TypeError('data.properties == None') 830 | self.pack_uint32(data.properties) 831 | 832 | def pack_fsinfo3res(self, data): 833 | if data.status is None: 834 | raise TypeError('data.status == None') 835 | self.pack_nfsstat3(data.status) 836 | if data.status == const.NFS3_OK: 837 | if data.resok is None: 838 | raise TypeError('data.resok == None') 839 | self.pack_fsinfo3resok(data.resok) 840 | else: 841 | if data.resfail is None: 842 | raise TypeError('data.resfail == None') 843 | self.pack_post_op_attr(data.resfail) 844 | 845 | def pack_pathconf3resok(self, data): 846 | if data.obj_attributes is None: 847 | raise TypeError('data.obj_attributes == None') 848 | self.pack_post_op_attr(data.obj_attributes) 849 | if data.linkmax is None: 850 | raise TypeError('data.linkmax == None') 851 | self.pack_uint32(data.linkmax) 852 | if data.name_max is None: 853 | raise TypeError('data.name_max == None') 854 | self.pack_uint32(data.name_max) 855 | if data.no_trunc is None: 856 | raise TypeError('data.no_trunc == None') 857 | self.pack_bool(data.no_trunc) 858 | if data.chown_restricted is None: 859 | raise TypeError('data.chown_restricted == None') 860 | self.pack_bool(data.chown_restricted) 861 | if data.case_insensitive is None: 862 | raise TypeError('data.case_insensitive == None') 863 | self.pack_bool(data.case_insensitive) 864 | if data.case_preserving is None: 865 | raise TypeError('data.case_preserving == None') 866 | self.pack_bool(data.case_preserving) 867 | 868 | def pack_pathconf3res(self, data): 869 | if data.status is None: 870 | raise TypeError('data.status == None') 871 | self.pack_nfsstat3(data.status) 872 | if data.status == const.NFS3_OK: 873 | if data.resok is None: 874 | raise TypeError('data.resok == None') 875 | self.pack_pathconf3resok(data.resok) 876 | else: 877 | if data.resfail is None: 878 | raise TypeError('data.resfail == None') 879 | self.pack_post_op_attr(data.resfail) 880 | 881 | def pack_commit3args(self, data): 882 | if data.file is None: 883 | raise TypeError('data.file == None') 884 | self.pack_nfs_fh3(data.file) 885 | if data.offset is None: 886 | raise TypeError('data.offset == None') 887 | self.pack_uint64(data.offset) 888 | if data.count is None: 889 | raise TypeError('data.count == None') 890 | self.pack_uint32(data.count) 891 | 892 | def pack_commit3resok(self, data): 893 | if data.file_wcc is None: 894 | raise TypeError('data.file_wcc == None') 895 | self.pack_wcc_data(data.file_wcc) 896 | if data.verf is None: 897 | raise TypeError('data.verf == None') 898 | self.pack_writeverf3(data.verf) 899 | 900 | def pack_commit3res(self, data): 901 | if data.status is None: 902 | raise TypeError('data.status == None') 903 | self.pack_nfsstat3(data.status) 904 | if data.status == const.NFS3_OK: 905 | if data.resok is None: 906 | raise TypeError('data.resok == None') 907 | self.pack_commit3resok(data.resok) 908 | else: 909 | if data.resfail is None: 910 | raise TypeError('data.resfail == None') 911 | self.pack_wcc_data(data.resfail) 912 | 913 | def pack_setaclargs(self, data): 914 | if data.dargs is None: 915 | raise TypeError('data.dargs == None') 916 | self.pack_diropargs3(data.dargs) 917 | if data.wargs is None: 918 | raise TypeError('data.wargs == None') 919 | self.pack_write3args(data.wargs) 920 | 921 | def pack_dirpath(self, data): 922 | if len(data) > const.NFS3_MNTPATHLEN: 923 | raise XDRError('array length too long for data') 924 | self.pack_string(data) 925 | 926 | def pack_name(self, data): 927 | if len(data) > const.NFS3_MNTNAMLEN: 928 | raise XDRError('array length too long for data') 929 | self.pack_string(data) 930 | 931 | def pack_fhandle3(self, data): 932 | if len(data) > const.NFS3_FHSIZE: 933 | raise XDRError('array length too long for data') 934 | self.pack_opaque(data) 935 | 936 | def pack_mountstat3(self, data): 937 | if data not in [const.MNT3_OK, const.MNT3ERR_PERM, const.MNT3ERR_NOENT, const.MNT3ERR_IO, const.MNT3ERR_ACCES, 938 | const.MNT3ERR_NOTDIR, const.MNT3ERR_INVAL, const.MNT3ERR_NAMETOOLONG, const.MNT3ERR_NOTSUPP, 939 | const.MNT3ERR_SERVERFAULT]: 940 | raise XDRError('value=%s not in enum mountstat3' % data) 941 | self.pack_int(data) 942 | 943 | def pack_mountres3_ok(self, data): 944 | if data.fhandle is None: 945 | raise TypeError('data.fhandle == None') 946 | self.pack_fhandle3(data.fhandle) 947 | if data.auth_flavors is None: 948 | raise TypeError('data.auth_flavors == None') 949 | self.pack_array(data.auth_flavors, self.pack_int) 950 | 951 | def pack_mountres3(self, data): 952 | if data.fhs_status is None: 953 | raise TypeError('data.fhs_status == None') 954 | self.pack_mountstat3(data.fhs_status) 955 | if data.fhs_status == const.MNT3_OK: 956 | if data.mountinfo is None: 957 | raise TypeError('data.mountinfo == None') 958 | self.pack_mountres3_ok(data.mountinfo) 959 | else: 960 | pass 961 | 962 | def pack_mountlist(self, data): 963 | if len(data) > 1: 964 | raise XDRError('array length too long for data') 965 | self.pack_array(data, self.pack_mountbody) 966 | 967 | def pack_mountbody(self, data): 968 | if data.ml_hostname is None: 969 | raise TypeError('data.ml_hostname == None') 970 | self.pack_name(data.ml_hostname) 971 | if data.ml_directory is None: 972 | raise TypeError('data.ml_directory == None') 973 | self.pack_dirpath(data.ml_directory) 974 | if data.ml_next is None: 975 | raise TypeError('data.ml_next == None') 976 | self.pack_mountlist(data.ml_next) 977 | 978 | def pack_groups(self, data): 979 | if len(data) > 1: 980 | raise XDRError('array length too long for data') 981 | self.pack_array(data, self.pack_groupnode) 982 | 983 | def pack_groupnode(self, data): 984 | if data.gr_name is None: 985 | raise TypeError('data.gr_name == None') 986 | self.pack_name(data.gr_name) 987 | if data.gr_next is None: 988 | raise TypeError('data.gr_next == None') 989 | self.pack_groups(data.gr_next) 990 | 991 | def pack_exports(self, data): 992 | if len(data) > 1: 993 | raise XDRError('array length too long for data') 994 | self.pack_array(data, self.pack_exportnode) 995 | 996 | def pack_exportnode(self, data): 997 | if data.ex_dir is None: 998 | raise TypeError('data.ex_dir == None') 999 | self.pack_dirpath(data.ex_dir) 1000 | if data.ex_groups is None: 1001 | raise TypeError('data.ex_groups == None') 1002 | self.pack_groups(data.ex_groups) 1003 | if data.ex_next is None: 1004 | raise TypeError('data.ex_next == None') 1005 | self.pack_exports(data.ex_next) 1006 | 1007 | 1008 | class nfs_pro_v3Unpacker(Unpacker): 1009 | unpack_hyper = Unpacker.unpack_hyper 1010 | unpack_string = Unpacker.unpack_string 1011 | unpack_int = Unpacker.unpack_int 1012 | unpack_float = Unpacker.unpack_float 1013 | unpack_uint = Unpacker.unpack_uint 1014 | unpack_opaque = Unpacker.unpack_opaque 1015 | unpack_double = Unpacker.unpack_double 1016 | unpack_unsigned = Unpacker.unpack_uint 1017 | unpack_quadruple = Unpacker.unpack_double 1018 | unpack_uhyper = Unpacker.unpack_uhyper 1019 | unpack_bool = Unpacker.unpack_bool 1020 | unpack_uint32 = unpack_uint 1021 | 1022 | def unpack_uint64(self): 1023 | i = self._Unpacker__pos 1024 | self._Unpacker__pos = j = i + 8 1025 | data = self._Unpacker__buf[i:j] 1026 | if len(data) < 8: 1027 | raise EOFError 1028 | return struct.unpack('>Q', data)[0] 1029 | 1030 | def unpack_filename3(self): 1031 | data = self.unpack_string() 1032 | return data 1033 | 1034 | def unpack_nfspath3(self): 1035 | data = self.unpack_string() 1036 | return data 1037 | 1038 | def unpack_cookieverf3(self): 1039 | data = self.unpack_fopaque(const.NFS3_COOKIEVERFSIZE) 1040 | return data 1041 | 1042 | def unpack_createverf3(self): 1043 | data = self.unpack_fopaque(const.NFS3_CREATEVERFSIZE) 1044 | return data 1045 | 1046 | def unpack_writeverf3(self): 1047 | data = self.unpack_fopaque(const.NFS3_WRITEVERFSIZE) 1048 | return data 1049 | 1050 | def unpack_nfsstat3(self): 1051 | data = self.unpack_int() 1052 | if data not in [const.NFS3_OK, const.NFS3ERR_PERM, const.NFS3ERR_NOENT, const.NFS3ERR_IO, const.NFS3ERR_NXIO, 1053 | const.NFS3ERR_ACCES, const.NFS3ERR_EXIST, const.NFS3ERR_XDEV, const.NFS3ERR_NODEV, 1054 | const.NFS3ERR_NOTDIR, const.NFS3ERR_ISDIR, const.NFS3ERR_INVAL, const.NFS3ERR_FBIG, 1055 | const.NFS3ERR_NOSPC, const.NFS3ERR_ROFS, const.NFS3ERR_MLINK, const.NFS3ERR_NAMETOOLONG, 1056 | const.NFS3ERR_NOTEMPTY, const.NFS3ERR_DQUOT, const.NFS3ERR_STALE, const.NFS3ERR_REMOTE, 1057 | const.NFS3ERR_BADHANDLE, const.NFS3ERR_NOT_SYNC, const.NFS3ERR_BAD_COOKIE, 1058 | const.NFS3ERR_NOTSUPP, const.NFS3ERR_TOOSMALL, const.NFS3ERR_SERVERFAULT, const.NFS3ERR_BADTYPE, 1059 | const.NFS3ERR_JUKEBOX]: 1060 | raise XDRError('value=%s not in enum nfsstat3' % data) 1061 | return data 1062 | 1063 | def unpack_ftype3(self): 1064 | data = self.unpack_int() 1065 | if data not in [const.NF3REG, const.NF3DIR, const.NF3BLK, const.NF3CHR, const.NF3LNK, const.NF3SOCK, 1066 | const.NF3FIFO]: 1067 | raise XDRError('value=%s not in enum ftype3' % data) 1068 | return data 1069 | 1070 | def unpack_specdata3(self, data_format='json'): 1071 | data = types.specdata3() 1072 | data.major = self.unpack_uint32() 1073 | data.minor = self.unpack_uint32() 1074 | return data.__dict__ if data_format == 'json' else data 1075 | 1076 | def unpack_nfs_fh3(self, data_format='json'): 1077 | data = types.nfs_fh3() 1078 | data.data = bytes(self.unpack_opaque()) 1079 | if len(data.data) > const.NFS3_FHSIZE: 1080 | raise XDRError('array length too long for data.data') 1081 | return data.__dict__ if data_format == 'json' else data 1082 | 1083 | def unpack_nfstime3(self, data_format='json'): 1084 | data = types.nfstime3() 1085 | data.seconds = self.unpack_uint32() 1086 | data.nseconds = self.unpack_uint32() 1087 | return data.__dict__ if data_format == 'json' else data 1088 | 1089 | def unpack_fattr3(self, data_format='json'): 1090 | data = types.fattr3() 1091 | data.type = self.unpack_ftype3() 1092 | data.mode = self.unpack_uint32() 1093 | data.nlink = self.unpack_uint32() 1094 | data.uid = self.unpack_uint32() 1095 | data.gid = self.unpack_uint32() 1096 | data.size = self.unpack_uint64() 1097 | data.used = self.unpack_uint64() 1098 | data.rdev = self.unpack_specdata3() 1099 | data.fsid = self.unpack_uint64() 1100 | data.fileid = self.unpack_uint64() 1101 | data.atime = self.unpack_nfstime3() 1102 | data.mtime = self.unpack_nfstime3() 1103 | data.ctime = self.unpack_nfstime3() 1104 | return data.__dict__ if data_format == 'json' else data 1105 | 1106 | def unpack_post_op_attr(self, data_format='json'): 1107 | data = types.post_op_attr() 1108 | data.present = self.unpack_bool() 1109 | if data.present == const.TRUE: 1110 | data.attributes = self.unpack_fattr3(data_format) 1111 | elif data.present == const.FALSE: 1112 | pass 1113 | else: 1114 | raise XDRError('bad switch=%s' % data.present) 1115 | return data.__dict__ if data_format == 'json' else data 1116 | 1117 | def unpack_wcc_attr(self, data_format='json'): 1118 | data = types.wcc_attr() 1119 | data.size = self.unpack_uint64() 1120 | data.mtime = self.unpack_nfstime3(data_format) 1121 | data.ctime = self.unpack_nfstime3(data_format) 1122 | return data.__dict__ if data_format == 'json' else data 1123 | 1124 | def unpack_pre_op_attr(self, data_format='json'): 1125 | data = types.pre_op_attr() 1126 | data.present = self.unpack_bool() 1127 | if data.present == const.TRUE: 1128 | data.attributes = self.unpack_wcc_attr(data_format) 1129 | elif data.present == const.FALSE: 1130 | pass 1131 | else: 1132 | raise XDRError('bad switch=%s' % data.present) 1133 | return data.__dict__ if data_format == 'json' else data 1134 | 1135 | def unpack_wcc_data(self, data_format='json'): 1136 | data = types.wcc_data() 1137 | data.before = self.unpack_pre_op_attr(data_format) 1138 | data.after = self.unpack_post_op_attr(data_format) 1139 | return data.__dict__ if data_format == 'json' else data 1140 | 1141 | def unpack_post_op_fh3(self, data_format='json'): 1142 | data = types.post_op_fh3() 1143 | data.present = self.unpack_bool() 1144 | if data.present == const.TRUE: 1145 | data.handle = self.unpack_nfs_fh3(data_format) 1146 | elif data.present == const.FALSE: 1147 | pass 1148 | else: 1149 | raise XDRError('bad switch=%s' % data.present) 1150 | return data.__dict__ if data_format == 'json' else data 1151 | 1152 | def unpack_set_uint32(self, data_format='json'): 1153 | data = types.set_uint32() 1154 | data.set = self.unpack_bool() 1155 | if data.set == const.TRUE: 1156 | data.val = self.unpack_uint32() 1157 | else: 1158 | pass 1159 | return data.__dict__ if data_format == 'json' else data 1160 | 1161 | def unpack_set_uint64(self, data_format='json'): 1162 | data = types.set_uint64() 1163 | data.set = self.unpack_bool() 1164 | if data.set == const.TRUE: 1165 | data.val = self.unpack_uint64() 1166 | else: 1167 | pass 1168 | return data.__dict__ if data_format == 'json' else data 1169 | 1170 | def unpack_time_how(self): 1171 | data = self.unpack_int() 1172 | if data not in [const.DONT_CHANGE, const.SET_TO_SERVER_TIME, const.SET_TO_CLIENT_TIME]: 1173 | raise XDRError('value=%s not in enum time_how' % data) 1174 | return data 1175 | 1176 | def unpack_set_time(self, data_format='json'): 1177 | data = types.set_time() 1178 | data.set = self.unpack_time_how() 1179 | if data.set == const.SET_TO_CLIENT_TIME: 1180 | data.time = self.unpack_nfstime3(data_format) 1181 | else: 1182 | pass 1183 | return data.__dict__ if data_format == 'json' else data 1184 | 1185 | def unpack_sattr3(self, data_format='json'): 1186 | data = types.sattr3() 1187 | data.mode = self.unpack_set_uint32() 1188 | data.uid = self.unpack_set_uint32() 1189 | data.gid = self.unpack_set_uint32() 1190 | data.size = self.unpack_set_uint64() 1191 | data.atime = self.unpack_set_time(data_format) 1192 | data.mtime = self.unpack_set_time(data_format) 1193 | return data.__dict__ if data_format == 'json' else data 1194 | 1195 | def unpack_diropargs3(self, data_format='json'): 1196 | data = types.diropargs3() 1197 | data.dir = self.unpack_nfs_fh3(data_format) 1198 | data.name = self.unpack_filename3() 1199 | return data.__dict__ if data_format == 'json' else data 1200 | 1201 | def unpack_diropres3ok(self, data_format='json'): 1202 | data = types.diropres3ok() 1203 | data.obj = self.unpack_post_op_fh3(data_format) 1204 | data.obj_attributes = self.unpack_post_op_attr(data_format) 1205 | data.dir_wcc = self.unpack_wcc_data(data_format) 1206 | return data.__dict__ if data_format == 'json' else data 1207 | 1208 | def unpack_diropres3(self, data_format='json'): 1209 | data = types.diropres3() 1210 | data.status = self.unpack_nfsstat3() 1211 | if data.status == const.NFS3_OK: 1212 | data.resok = self.unpack_diropres3ok(data_format) 1213 | else: 1214 | data.resfail = self.unpack_wcc_data(data_format) 1215 | return data.__dict__ if data_format == 'json' else data 1216 | 1217 | def unpack_wccstat3(self, data_format='json'): 1218 | data = types.wccstat3() 1219 | data.status = self.unpack_nfsstat3() 1220 | if data.status == -1: 1221 | pass 1222 | else: 1223 | data.wcc = self.unpack_wcc_data(data_format) 1224 | return data.__dict__ if data_format == 'json' else data 1225 | 1226 | def unpack_getattr3res(self, data_format='json'): 1227 | data = types.getattr3res() 1228 | data.status = self.unpack_nfsstat3() 1229 | if data.status == const.NFS3_OK: 1230 | data.attributes = self.unpack_fattr3(data_format) 1231 | else: 1232 | pass 1233 | return data.__dict__ if data_format == 'json' else data 1234 | 1235 | def unpack_sattrguard3(self, data_format='json'): 1236 | data = types.sattrguard3() 1237 | data.check = self.unpack_bool() 1238 | if data.check == const.TRUE: 1239 | data.ctime = self.unpack_nfstime3(data_format) 1240 | elif data.check == const.FALSE: 1241 | pass 1242 | else: 1243 | raise XDRError('bad switch=%s' % data.check) 1244 | return data.__dict__ if data_format == 'json' else data 1245 | 1246 | def unpack_setattr3args(self, data_format='json'): 1247 | data = types.setattr3args() 1248 | data.object = self.unpack_nfs_fh3(data_format) 1249 | data.new_attributes = self.unpack_sattr3(data_format) 1250 | data.guard = self.unpack_sattrguard3(data_format) 1251 | return data.__dict__ if data_format == 'json' else data 1252 | 1253 | def unpack_wccdata3res(self, category, data_format='json'): 1254 | data = types.wcc_data3res(category=category) 1255 | data.status = self.unpack_nfsstat3() 1256 | data.wcc_data = self.unpack_wcc_data(data_format) 1257 | if data_format == 'json': 1258 | res = data.__dict__ 1259 | res.pop("category") 1260 | if res["status"] == const.NFS3_OK: 1261 | res["resok"] = res["wcc_data"] 1262 | else: 1263 | res["resfail"] = res["wcc_data"] 1264 | res.pop("wcc_data") 1265 | return res 1266 | else: 1267 | return data 1268 | 1269 | def unpack_setattr3res(self, data_format='json'): 1270 | return self.unpack_wccdata3res(category='setattr3res', data_format=data_format) 1271 | 1272 | def unpack_lookup3resok(self, data_format='json'): 1273 | data = types.lookup3resok() 1274 | data.object = self.unpack_nfs_fh3(data_format) 1275 | data.obj_attributes = self.unpack_post_op_attr(data_format) 1276 | data.dir_attributes = self.unpack_post_op_attr(data_format) 1277 | return data.__dict__ if data_format == 'json' else data 1278 | 1279 | def unpack_lookup3res(self, data_format='json'): 1280 | data = types.lookup3res() 1281 | data.status = self.unpack_nfsstat3() 1282 | if data.status == const.NFS3_OK: 1283 | data.resok = self.unpack_lookup3resok(data_format) 1284 | else: 1285 | data.resfail = self.unpack_post_op_attr(data_format) 1286 | return data.__dict__ if data_format == 'json' else data 1287 | 1288 | def unpack_access3args(self, data_format='json'): 1289 | data = types.access3args() 1290 | data.object = self.unpack_nfs_fh3(data_format) 1291 | data.access = self.unpack_uint32() 1292 | return data.__dict__ if data_format == 'json' else data 1293 | 1294 | def unpack_access3resok(self, data_format='json'): 1295 | data = types.access3resok() 1296 | data.obj_attributes = self.unpack_post_op_attr(data_format) 1297 | data.access = self.unpack_uint32() 1298 | return data.__dict__ if data_format == 'json' else data 1299 | 1300 | def unpack_access3res(self, data_format='json'): 1301 | data = types.access3res() 1302 | data.status = self.unpack_nfsstat3() 1303 | if data.status == const.NFS3_OK: 1304 | data.resok = self.unpack_access3resok(data_format) 1305 | else: 1306 | data.resfail = self.unpack_post_op_attr(data_format) 1307 | return data.__dict__ if data_format == 'json' else data 1308 | 1309 | def unpack_readlink3resok(self, data_format='json'): 1310 | data = types.readlink3resok() 1311 | data.symlink_attributes = self.unpack_post_op_attr(data_format) 1312 | data.data = self.unpack_nfspath3() 1313 | return data.__dict__ if data_format == 'json' else data 1314 | 1315 | def unpack_readlink3res(self, data_format='json'): 1316 | data = types.readlink3res() 1317 | data.status = self.unpack_nfsstat3() 1318 | if data.status == const.NFS3_OK: 1319 | data.resok = self.unpack_readlink3resok(data_format) 1320 | else: 1321 | data.resfail = self.unpack_post_op_attr(data_format) 1322 | return data.__dict__ if data_format == 'json' else data 1323 | 1324 | def unpack_read3args(self, data_format='json'): 1325 | data = types.read3args() 1326 | data.file = self.unpack_nfs_fh3(data_format) 1327 | data.offset = self.unpack_uint64() 1328 | data.count = self.unpack_uint32() 1329 | return data.__dict__ if data_format == 'json' else data 1330 | 1331 | def unpack_read3resok(self, data_format='json'): 1332 | data = types.read3resok() 1333 | data.file_attributes = self.unpack_post_op_attr(data_format) 1334 | data.count = self.unpack_uint32() 1335 | data.eof = self.unpack_bool() 1336 | data.data = self.unpack_opaque() 1337 | return data.__dict__ if data_format == 'json' else data 1338 | 1339 | def unpack_read3res(self, data_format='json'): 1340 | data = types.read3res() 1341 | data.status = self.unpack_nfsstat3() 1342 | if data.status == const.NFS3_OK: 1343 | data.resok = self.unpack_read3resok(data_format) 1344 | else: 1345 | data.resfail = self.unpack_post_op_attr(data_format) 1346 | return data.__dict__ if data_format == 'json' else data 1347 | 1348 | def unpack_stable_how(self): 1349 | data = self.unpack_int() 1350 | if data not in [const.UNSTABLE, const.DATA_SYNC, const.FILE_SYNC]: 1351 | raise XDRError('value=%s not in enum stable_how' % data) 1352 | return data 1353 | 1354 | def unpack_write3args(self, data_format='json'): 1355 | data = types.write3args() 1356 | data.file = self.unpack_nfs_fh3(data_format) 1357 | data.offset = self.unpack_uint64() 1358 | data.count = self.unpack_uint32() 1359 | data.stable = self.unpack_stable_how() 1360 | data.data = self.unpack_opaque() 1361 | return data.__dict__ if data_format == 'json' else data 1362 | 1363 | def unpack_write3resok(self, data_format='json'): 1364 | data = types.write3resok() 1365 | data.file_wcc = self.unpack_wcc_data(data_format) 1366 | data.count = self.unpack_uint32() 1367 | data.committed = self.unpack_stable_how() 1368 | data.verf = self.unpack_writeverf3() 1369 | return data.__dict__ if data_format == 'json' else data 1370 | 1371 | def unpack_write3res(self, data_format='json'): 1372 | data = types.write3res() 1373 | data.status = self.unpack_nfsstat3() 1374 | if data.status == const.NFS3_OK: 1375 | data.resok = self.unpack_write3resok(data_format) 1376 | else: 1377 | data.resfail = self.unpack_wcc_data(data_format) 1378 | return data.__dict__ if data_format == 'json' else data 1379 | 1380 | def unpack_createmode3(self): 1381 | data = self.unpack_int() 1382 | if data not in [const.UNCHECKED, const.GUARDED, const.EXCLUSIVE]: 1383 | raise XDRError('value=%s not in enum createmode3' % data) 1384 | return data 1385 | 1386 | def unpack_createhow3(self, data_format='json'): 1387 | data = types.createhow3() 1388 | data.mode = self.unpack_createmode3() 1389 | if data.mode == const.UNCHECKED or data.mode == const.GUARDED: 1390 | data.obj_attributes = self.unpack_sattr3(data_format) 1391 | elif data.mode == const.EXCLUSIVE: 1392 | data.verf = self.unpack_createverf3() 1393 | else: 1394 | raise XDRError('bad switch=%s' % data.mode) 1395 | return data.__dict__ if data_format == 'json' else data 1396 | 1397 | def unpack_create3args(self, data_format='json'): 1398 | data = types.create3args() 1399 | data.where = self.unpack_diropargs3(data_format) 1400 | data.how = self.unpack_createhow3(data_format) 1401 | return data.__dict__ if data_format == 'json' else data 1402 | 1403 | def unpack_create3resok(self, data_format='json'): 1404 | data = types.create3resok() 1405 | data.obj = self.unpack_post_op_fh3() 1406 | data.obj_attributes = self.unpack_post_op_attr(data_format) 1407 | data.dir_wcc = self.unpack_wcc_data(data_format) 1408 | return data.__dict__ if data_format == 'json' else data 1409 | 1410 | def unpack_create3res(self, data_format='json'): 1411 | data = types.create3res() 1412 | data.status = self.unpack_nfsstat3() 1413 | if data.status == const.NFS3_OK: 1414 | data.resok = self.unpack_create3resok(data_format) 1415 | else: 1416 | data.resfail = self.unpack_wcc_data(data_format) 1417 | return data.__dict__ if data_format == 'json' else data 1418 | 1419 | def unpack_mkdir3args(self, data_format='json'): 1420 | data = types.mkdir3args() 1421 | data.where = self.unpack_diropargs3(data_format) 1422 | data.attributes = self.unpack_sattr3(data_format) 1423 | return data.__dict__ if data_format == 'json' else data 1424 | 1425 | unpack_mkdir3res = unpack_create3res 1426 | 1427 | def unpack_symlinkdata3(self, data_format='json'): 1428 | data = types.symlinkdata3() 1429 | data.symlink_attributes = self.unpack_sattr3(data_format) 1430 | data.symlink_data = self.unpack_nfspath3() 1431 | return data.__dict__ if data_format == 'json' else data 1432 | 1433 | def unpack_symlink3args(self, data_format='json'): 1434 | data = types.symlink3args() 1435 | data.where = self.unpack_diropargs3(data_format) 1436 | data.symlink = self.unpack_symlinkdata3(data_format) 1437 | return data.__dict__ if data_format == 'json' else data 1438 | 1439 | unpack_symlink3res = unpack_create3res 1440 | 1441 | def unpack_devicedata3(self, data_format='json'): 1442 | data = types.devicedata3() 1443 | data.dev_attributes = self.unpack_sattr3(data_format) 1444 | data.spec = self.unpack_specdata3(data_format) 1445 | return data.__dict__ if data_format == 'json' else data 1446 | 1447 | def unpack_mknoddata3(self, data_format='json'): 1448 | data = types.mknoddata3() 1449 | data.type = self.unpack_ftype3() 1450 | if data.type == const.NF3CHR or data.type == const.NF3BLK: 1451 | data.device = self.unpack_devicedata3(data_format) 1452 | elif data.type == const.NF3SOCK or data.type == const.NF3FIFO: 1453 | data.pipe_attributes = self.unpack_sattr3(data_format) 1454 | else: 1455 | pass 1456 | return data.__dict__ if data_format == 'json' else data 1457 | 1458 | def unpack_mknod3args(self, data_format='json'): 1459 | data = types.mknod3args() 1460 | data.where = self.unpack_diropargs3(data_format) 1461 | data.what = self.unpack_mknoddata3(data_format) 1462 | return data.__dict__ if data_format == 'json' else data 1463 | 1464 | unpack_mknod3res = unpack_create3res 1465 | 1466 | def unpack_remove3res(self, data_format='json'): 1467 | return self.unpack_wccdata3res(category='remove3res', data_format=data_format) 1468 | 1469 | def unpack_rmdir3res(self, data_format='json'): 1470 | return self.unpack_wccdata3res(category='rmdir3res', data_format=data_format) 1471 | 1472 | def unpack_rename3args(self, data_format='json'): 1473 | data = types.rename3args() 1474 | data.from_v = self.unpack_diropargs3(data_format) 1475 | data.to = self.unpack_diropargs3(data_format) 1476 | return data.__dict__ if data_format == 'json' else data 1477 | 1478 | def unpack_rename3wcc(self, data_format='json'): 1479 | data = types.rename3wcc() 1480 | data.fromdir_wcc = self.unpack_wcc_data(data_format) 1481 | data.todir_wcc = self.unpack_wcc_data(data_format) 1482 | return data.__dict__ if data_format == 'json' else data 1483 | 1484 | def unpack_rename3res(self, data_format='json'): 1485 | data = types.rename3res() 1486 | data.status = self.unpack_nfsstat3() 1487 | if data.status == -1: 1488 | pass 1489 | else: 1490 | data.res = self.unpack_rename3wcc(data_format) 1491 | return data.__dict__ if data_format == 'json' else data 1492 | 1493 | def unpack_link3args(self, data_format='json'): 1494 | data = types.link3args() 1495 | data.file = self.unpack_nfs_fh3(data_format) 1496 | data.link = self.unpack_diropargs3(data_format) 1497 | return data.__dict__ if data_format == 'json' else data 1498 | 1499 | def unpack_link3wcc(self, data_format='json'): 1500 | data = types.link3wcc() 1501 | data.file_attributes = self.unpack_post_op_attr(data_format) 1502 | data.linkdir_wcc = self.unpack_wcc_data(data_format) 1503 | return data.__dict__ if data_format == 'json' else data 1504 | 1505 | def unpack_link3res(self, data_format='json'): 1506 | data = types.link3res() 1507 | data.status = self.unpack_nfsstat3() 1508 | if data.status == -1: 1509 | pass 1510 | else: 1511 | data.res = self.unpack_link3wcc(data_format) 1512 | return data.__dict__ if data_format == 'json' else data 1513 | 1514 | def unpack_readdir3args(self, data_format='json'): 1515 | data = types.readdir3args() 1516 | data.dir = self.unpack_nfs_fh3(data_format) 1517 | data.cookie = self.unpack_uint64() 1518 | data.cookieverf = self.unpack_cookieverf3() 1519 | data.count = self.unpack_uint32() 1520 | return data.__dict__ if data_format == 'json' else data 1521 | 1522 | def unpack_entry3(self, data_format='json'): 1523 | data = types.entry3() 1524 | data.fileid = self.unpack_uint64() 1525 | data.name = self.unpack_filename3() 1526 | data.cookie = self.unpack_uint64() 1527 | data.nextentry = self.unpack_array(self.unpack_entry3) 1528 | if len(data.nextentry) > 1: 1529 | raise XDRError('array length too long for data.nextentry') 1530 | return data.__dict__ if data_format == 'json' else data 1531 | 1532 | def unpack_dirlist3(self, data_format='json'): 1533 | data = types.dirlist3() 1534 | data.entries = self.unpack_array(self.unpack_entry3) 1535 | if len(data.entries) > 1: 1536 | raise XDRError('array length too long for data.entries') 1537 | data.eof = self.unpack_bool() 1538 | return data.__dict__ if data_format == 'json' else data 1539 | 1540 | def unpack_readdir3resok(self, data_format='json'): 1541 | data = types.readdir3resok() 1542 | data.dir_attributes = self.unpack_post_op_attr(data_format) 1543 | data.cookieverf = self.unpack_cookieverf3() 1544 | data.reply = self.unpack_dirlist3(data_format) 1545 | return data.__dict__ if data_format == 'json' else data 1546 | 1547 | def unpack_readdir3res(self, data_format='json'): 1548 | data = types.readdir3res() 1549 | data.status = self.unpack_nfsstat3() 1550 | if data.status == const.NFS3_OK: 1551 | data.resok = self.unpack_readdir3resok(data_format) 1552 | else: 1553 | data.resfail = self.unpack_post_op_attr(data_format) 1554 | return data.__dict__ if data_format == 'json' else data 1555 | 1556 | def unpack_readdirplus3args(self, data_format='json'): 1557 | data = types.readdirplus3args() 1558 | data.dir = self.unpack_nfs_fh3(data_format) 1559 | data.cookie = self.unpack_uint64() 1560 | data.cookieverf = self.unpack_cookieverf3() 1561 | data.dircount = self.unpack_uint32() 1562 | data.maxcount = self.unpack_uint32() 1563 | return data.__dict__ if data_format == 'json' else data 1564 | 1565 | def unpack_entryplus3(self, data_format='json'): 1566 | data = types.entryplus3() 1567 | data.fileid = self.unpack_uint64() 1568 | data.name = self.unpack_filename3() 1569 | data.cookie = self.unpack_uint64() 1570 | data.name_attributes = self.unpack_post_op_attr(data_format) 1571 | data.name_handle = self.unpack_post_op_fh3(data_format) 1572 | data.nextentry = self.unpack_array(self.unpack_entryplus3) 1573 | if len(data.nextentry) > 1: 1574 | raise XDRError('array length too long for data.nextentry') 1575 | return data.__dict__ if data_format == 'json' else data 1576 | 1577 | def unpack_dirlistplus3(self, data_format='json'): 1578 | data = types.dirlistplus3() 1579 | data.entries = self.unpack_array(self.unpack_entryplus3) 1580 | if len(data.entries) > 1: 1581 | raise XDRError('array length too long for data.entries') 1582 | data.eof = self.unpack_bool() 1583 | return data.__dict__ if data_format == 'json' else data 1584 | 1585 | def unpack_readdirplus3resok(self, data_format='json'): 1586 | data = types.readdirplus3resok() 1587 | data.dir_attributes = self.unpack_post_op_attr(data_format) 1588 | data.cookieverf = self.unpack_cookieverf3() 1589 | data.reply = self.unpack_dirlistplus3(data_format) 1590 | return data.__dict__ if data_format == 'json' else data 1591 | 1592 | def unpack_readdirplus3res(self, data_format='json'): 1593 | data = types.readdirplus3res() 1594 | data.status = self.unpack_nfsstat3() 1595 | if data.status == const.NFS3_OK: 1596 | data.resok = self.unpack_readdirplus3resok(data_format) 1597 | else: 1598 | data.resfail = self.unpack_post_op_attr(data_format) 1599 | return data.__dict__ if data_format == 'json' else data 1600 | 1601 | def unpack_fsstat3resok(self, data_format='json'): 1602 | data = types.fsstat3resok() 1603 | data.obj_attributes = self.unpack_post_op_attr(data_format) 1604 | data.tbytes = self.unpack_uint64() 1605 | data.fbytes = self.unpack_uint64() 1606 | data.abytes = self.unpack_uint64() 1607 | data.tfiles = self.unpack_uint64() 1608 | data.ffiles = self.unpack_uint64() 1609 | data.afiles = self.unpack_uint64() 1610 | data.invarsec = self.unpack_uint32() 1611 | return data.__dict__ if data_format == 'json' else data 1612 | 1613 | def unpack_fsstat3res(self, data_format='json'): 1614 | data = types.fsstat3res() 1615 | data.status = self.unpack_nfsstat3() 1616 | if data.status == const.NFS3_OK: 1617 | data.resok = self.unpack_fsstat3resok(data_format) 1618 | else: 1619 | data.resfail = self.unpack_post_op_attr(data_format) 1620 | return data.__dict__ if data_format == 'json' else data 1621 | 1622 | def unpack_fsinfo3resok(self, data_format='json'): 1623 | data = types.fsinfo3resok() 1624 | data.obj_attributes = self.unpack_post_op_attr(data_format) 1625 | data.rtmax = self.unpack_uint32() 1626 | data.rtpref = self.unpack_uint32() 1627 | data.rtmult = self.unpack_uint32() 1628 | data.wtmax = self.unpack_uint32() 1629 | data.wtpref = self.unpack_uint32() 1630 | data.wtmult = self.unpack_uint32() 1631 | data.dtpref = self.unpack_uint32() 1632 | data.maxfilesize = self.unpack_uint64() 1633 | data.time_delta = self.unpack_nfstime3(data_format) 1634 | data.properties = self.unpack_uint32() 1635 | return data.__dict__ if data_format == 'json' else data 1636 | 1637 | def unpack_fsinfo3res(self, data_format='json'): 1638 | data = types.fsinfo3res() 1639 | data.status = self.unpack_nfsstat3() 1640 | if data.status == const.NFS3_OK: 1641 | data.resok = self.unpack_fsinfo3resok(data_format) 1642 | else: 1643 | data.resfail = self.unpack_post_op_attr(data_format) 1644 | return data.__dict__ if data_format == 'json' else data 1645 | 1646 | def unpack_pathconf3resok(self, data_format='json'): 1647 | data = types.pathconf3resok() 1648 | data.obj_attributes = self.unpack_post_op_attr(data_format) 1649 | data.linkmax = self.unpack_uint32() 1650 | data.name_max = self.unpack_uint32() 1651 | data.no_trunc = self.unpack_bool() 1652 | data.chown_restricted = self.unpack_bool() 1653 | data.case_insensitive = self.unpack_bool() 1654 | data.case_preserving = self.unpack_bool() 1655 | return data.__dict__ if data_format == 'json' else data 1656 | 1657 | def unpack_pathconf3res(self, data_format='json'): 1658 | data = types.pathconf3res() 1659 | data.status = self.unpack_nfsstat3() 1660 | if data.status == const.NFS3_OK: 1661 | data.resok = self.unpack_pathconf3resok(data_format) 1662 | else: 1663 | data.resfail = self.unpack_post_op_attr(data_format) 1664 | return data.__dict__ if data_format == 'json' else data 1665 | 1666 | def unpack_commit3args(self, data_format='json'): 1667 | data = types.commit3args() 1668 | data.file = self.unpack_nfs_fh3(data_format) 1669 | data.offset = self.unpack_uint64() 1670 | data.count = self.unpack_uint32() 1671 | return data.__dict__ if data_format == 'json' else data 1672 | 1673 | def unpack_commit3resok(self, data_format='json'): 1674 | data = types.commit3resok() 1675 | data.file_wcc = self.unpack_wcc_data(data_format) 1676 | data.verf = self.unpack_writeverf3() 1677 | return data.__dict__ if data_format == 'json' else data 1678 | 1679 | def unpack_commit3res(self, data_format='json'): 1680 | data = types.commit3res() 1681 | data.status = self.unpack_nfsstat3() 1682 | if data.status == const.NFS3_OK: 1683 | data.resok = self.unpack_commit3resok(data_format) 1684 | else: 1685 | data.resfail = self.unpack_wcc_data(data_format) 1686 | return data.__dict__ if data_format == 'json' else data 1687 | 1688 | def unpack_setaclargs(self, data_format='json'): 1689 | data = types.setaclargs() 1690 | data.dargs = self.unpack_diropargs3(data_format) 1691 | data.wargs = self.unpack_write3args(data_format) 1692 | return data.__dict__ if data_format == 'json' else data 1693 | 1694 | def unpack_dirpath(self): 1695 | data = self.unpack_string() 1696 | if len(data) > const.NFS3_MNTPATHLEN: 1697 | raise XDRError('array length too long for data') 1698 | return data 1699 | 1700 | def unpack_name(self): 1701 | data = self.unpack_string() 1702 | if len(data) > const.NFS3_MNTNAMLEN: 1703 | raise XDRError('array length too long for data') 1704 | return data 1705 | 1706 | def unpack_fhandle3(self): 1707 | data = self.unpack_opaque() 1708 | if len(data) > const.NFS3_FHSIZE: 1709 | raise XDRError('array length too long for data') 1710 | return data 1711 | 1712 | def unpack_mountstat3(self): 1713 | data = self.unpack_int() 1714 | if data not in [const.MNT3_OK, const.MNT3ERR_PERM, const.MNT3ERR_NOENT, const.MNT3ERR_IO, const.MNT3ERR_ACCES, 1715 | const.MNT3ERR_NOTDIR, const.MNT3ERR_INVAL, const.MNT3ERR_NAMETOOLONG, const.MNT3ERR_NOTSUPP, 1716 | const.MNT3ERR_SERVERFAULT]: 1717 | raise XDRError('value=%s not in enum mountstat3' % data) 1718 | return data 1719 | 1720 | def unpack_mountres3_ok(self, data_format='json'): 1721 | data = types.mountres3_ok() 1722 | data.fhandle = self.unpack_fhandle3() 1723 | data.auth_flavors = self.unpack_array(self.unpack_int) 1724 | return data.__dict__ if data_format == 'json' else data 1725 | 1726 | def unpack_mountres3(self, data_format='json'): 1727 | data = types.mountres3() 1728 | data.status = self.unpack_mountstat3() 1729 | if data.status == const.MNT3_OK: 1730 | data.mountinfo = self.unpack_mountres3_ok(data_format) 1731 | else: 1732 | pass 1733 | return data.__dict__ if data_format == 'json' else data 1734 | 1735 | def unpack_mountlist(self): 1736 | data = self.unpack_array(self.unpack_mountbody) 1737 | if len(data) > 1: 1738 | raise XDRError('array length too long for data') 1739 | return data 1740 | 1741 | def unpack_mountbody(self, data_format='json'): 1742 | data = types.mountbody() 1743 | data.ml_hostname = self.unpack_name() 1744 | data.ml_directory = self.unpack_dirpath() 1745 | data.ml_next = self.unpack_mountlist() 1746 | return data.__dict__ if data_format == 'json' else data 1747 | 1748 | def unpack_groups(self): 1749 | data = self.unpack_array(self.unpack_groupnode) 1750 | if len(data) > 1: 1751 | raise XDRError('array length too long for data') 1752 | return data 1753 | 1754 | def unpack_groupnode(self): 1755 | data = types.groupnode() 1756 | data.gr_name = self.unpack_name() 1757 | data.gr_next = self.unpack_groups() 1758 | return data 1759 | 1760 | def unpack_exports(self): 1761 | data = self.unpack_array(self.unpack_exportnode) 1762 | if len(data) > 1: 1763 | raise XDRError('array length too long for data') 1764 | return data 1765 | 1766 | def unpack_exportnode(self): 1767 | data = types.exportnode() 1768 | data.ex_dir = self.unpack_dirpath() 1769 | data.ex_groups = self.unpack_groups() 1770 | data.ex_next = self.unpack_exports() 1771 | return data 1772 | -------------------------------------------------------------------------------- /pyNfsClient/portmap.py: -------------------------------------------------------------------------------- 1 | import struct 2 | from .rpc import RPC 3 | from .const import PORTMAP_PROGRAM, PORTMAP_VERSION, PORTMAP_PORT 4 | 5 | 6 | class Portmap(RPC): 7 | program = PORTMAP_PROGRAM # Portmap 8 | program_version = PORTMAP_VERSION 9 | port = PORTMAP_PORT 10 | 11 | def __init__(self, host, timeout=6000): 12 | super(Portmap, self).__init__(host, Portmap.port, timeout) 13 | 14 | def null(self): 15 | procedure = 0 # Null 16 | 17 | super(Portmap, self).request(self.program, self.program_version, procedure) 18 | 19 | # no exception raised 20 | return True 21 | 22 | def dump(self): 23 | procedure = 4 # Dump 24 | 25 | proto = struct.pack('!LL', self.program_version, procedure) 26 | 27 | portmap = super(Portmap, self).request(self.program, self.program_version, procedure, data=proto) 28 | 29 | rpc_map_entries = list() 30 | 31 | if len(portmap) <= 4: # portmap_Value_Follows + one portmap_Map_entry 32 | return rpc_map_entries 33 | 34 | portmap_value_follows = portmap[0:4] 35 | portmap_map_entries = portmap[4:] 36 | 37 | while portmap_value_follows == b'\x00\x00\x00\x01': 38 | ( 39 | program, 40 | version, 41 | protocol, 42 | port 43 | ) = struct.unpack('!LLLL', portmap_map_entries[:16]) 44 | portmap_map_entries = portmap_map_entries[16:] 45 | 46 | if protocol == 0x06: 47 | protocol = 'tcp' 48 | elif protocol == 0x11: 49 | protocol = 'udp' 50 | else: 51 | protocol = 'unknown'.format(protocol) 52 | 53 | _ = {'program': program, 'version': version, 'protocol': protocol, 'port': port} 54 | if _ not in rpc_map_entries: 55 | rpc_map_entries.append(_) 56 | 57 | portmap_value_follows = portmap_map_entries[0:4] 58 | portmap_map_entries = portmap_map_entries[4:] 59 | 60 | return rpc_map_entries 61 | 62 | def getport(self, getport_program, getport_program_version, getport_protocol=6): 63 | # RPC 64 | program = 100000 # Portmap 65 | program_version = 2 66 | procedure = 3 # GetPort 67 | 68 | # GetPort 69 | getport_port = 0 70 | 71 | proto = struct.pack('!LLLL', getport_program, getport_program_version, getport_protocol, getport_port) 72 | 73 | getport = super(Portmap, self).request(program, program_version, procedure, data=proto) 74 | 75 | (port,) = struct.unpack('!L', getport) 76 | return port 77 | -------------------------------------------------------------------------------- /pyNfsClient/rpc.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import struct 3 | import socket 4 | import time 5 | from random import randint 6 | 7 | logger = logging.getLogger(__package__) 8 | 9 | 10 | class RPCProtocolError(Exception): 11 | pass 12 | 13 | 14 | class RPC(object): 15 | connections = list() 16 | 17 | def __init__(self, host, port, timeout): 18 | self.host = host 19 | self.port = port 20 | self.timeout = timeout 21 | self.client = None 22 | self.client_port = None 23 | 24 | def request(self, program, program_version, procedure, data=None, message_type=0, version=2, auth=None): 25 | 26 | rpc_xid = int(time.time()) 27 | rpc_message_type = message_type # 0=call 28 | rpc_rpc_version = version 29 | rpc_program = program 30 | rpc_program_version = program_version 31 | rpc_procedure = procedure 32 | rpc_verifier_flavor = 0 # AUTH_NULL 33 | rpc_verifier_length = 0 34 | 35 | proto = struct.pack( 36 | # Remote Procedure Call 37 | '!LLLLLL', 38 | rpc_xid, 39 | rpc_message_type, 40 | rpc_rpc_version, 41 | rpc_program, 42 | rpc_program_version, 43 | rpc_procedure, 44 | ) 45 | 46 | if auth is None: # AUTH_NULL 47 | proto += struct.pack( 48 | '!LL', 49 | 0, 50 | 0, 51 | ) 52 | elif auth["flavor"] == 1: # AUTH_UNIX 53 | stamp = int(time.time()) & 0xffff 54 | auth_data = struct.pack( 55 | "!LL", 56 | stamp, 57 | len(auth["machine_name"]) 58 | ) 59 | auth_data += auth["machine_name"].encode() 60 | auth_data += b'\x00'*((4-len(auth["machine_name"]) % 4) % 4) 61 | auth_data += struct.pack( 62 | "!LL", 63 | auth["uid"], 64 | auth["gid"], 65 | ) 66 | if len(auth['aux_gid']) == 1 and auth['aux_gid'][0] == 0: 67 | auth_data += struct.pack("!L", 0) 68 | else: 69 | auth_data += struct.pack("!L", len(auth["aux_gid"])) 70 | for aux_gid in auth["aux_gid"]: 71 | auth_data += struct.pack("!L", aux_gid) 72 | 73 | proto += struct.pack( 74 | '!LL', 75 | 1, 76 | len(auth_data), 77 | ) 78 | proto += auth_data 79 | 80 | else: 81 | raise Exception("RPC unknown auth method") 82 | 83 | proto += struct.pack( 84 | '!LL', 85 | rpc_verifier_flavor, 86 | rpc_verifier_length, 87 | ) 88 | 89 | if data is not None: 90 | proto += data 91 | 92 | rpc_fragment_header = 0x80000000 + len(proto) 93 | 94 | proto = struct.pack('!L', rpc_fragment_header) + proto 95 | 96 | try: 97 | self.client.send(proto) 98 | 99 | last_fragment = False 100 | data = b"" 101 | 102 | while not last_fragment: 103 | response = self.recv() 104 | 105 | last_fragment = struct.unpack('!L', response[:4])[0] & 0x80000000 != 0 106 | 107 | data += response[4:] 108 | 109 | rpc = data[:24] 110 | ( 111 | rpc_XID, 112 | rpc_Message_Type, 113 | rpc_Reply_State, 114 | rpc_Verifier_Flavor, 115 | rpc_Verifier_Length, 116 | rpc_Accept_State 117 | ) = struct.unpack('!LLLLLL', rpc) 118 | 119 | if rpc_Message_Type != 1 or rpc_Reply_State != 0 or rpc_Accept_State != 0: 120 | raise Exception("RPC protocol error") 121 | 122 | data = data[24:] 123 | except Exception as e: 124 | logger.exception(e) 125 | 126 | return data 127 | 128 | def connect(self): 129 | self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 130 | self.client.settimeout(self.timeout) 131 | # if we are running as root, use a source port between 500 and 1024 (NFS security options...) 132 | random_port = None 133 | try: 134 | i = 0 135 | while True: 136 | try: 137 | random_port = randint(500, 1023) 138 | i += 1 139 | self.client.bind(('', random_port)) 140 | self.client_port = random_port 141 | logger.debug("Port %d occupied" % self.client_port) 142 | break 143 | except: 144 | logger.warning("Socket port binding with %d failed in loop %d, try again." % (random_port, i)) 145 | continue 146 | except Exception as e: 147 | logger.error(e) 148 | 149 | self.client.connect((self.host, self.port)) 150 | RPC.connections.append(self) 151 | 152 | def disconnect(self): 153 | self.client.close() 154 | logger.debug("Port %s released" % self.client_port) 155 | 156 | @classmethod 157 | def disconnect_all(cls): 158 | counter = 0 159 | for item in cls.connections: 160 | try: 161 | item.client.close() 162 | counter += 1 163 | except: 164 | pass 165 | logger.debug("Disconnect all connecting rpc sockets, amount: %d" % counter) 166 | 167 | def recv(self): 168 | rpc_response_size = b"" 169 | 170 | try: 171 | while len(rpc_response_size) != 4: 172 | rpc_response_size = self.client.recv(4) 173 | 174 | if len(rpc_response_size) != 4: 175 | raise RPCProtocolError("incorrect recv response size: %d" % len(rpc_response_size)) 176 | response_size = struct.unpack('!L', rpc_response_size)[0] & 0x7fffffff 177 | 178 | rpc_response = rpc_response_size 179 | while len(rpc_response) < response_size: 180 | rpc_response = rpc_response + self.client.recv(response_size-len(rpc_response)+4) 181 | 182 | return rpc_response 183 | except Exception as e: 184 | logger.exception(e) 185 | -------------------------------------------------------------------------------- /pyNfsClient/rtypes.py: -------------------------------------------------------------------------------- 1 | from . import const 2 | 3 | 4 | class specdata3: 5 | # XDR definition: 6 | # struct specdata3 { 7 | # uint32 major; 8 | # uint32 minor; 9 | # }; 10 | def __init__(self, major=None, minor=None): 11 | self.major = major 12 | self.minor = minor 13 | 14 | def __repr__(self): 15 | out = [] 16 | if self.major is not None: 17 | out += ['major=%s' % repr(self.major)] 18 | if self.minor is not None: 19 | out += ['minor=%s' % repr(self.minor)] 20 | return 'specdata3(%s)' % ', '.join(out) 21 | 22 | 23 | class nfs_fh3: 24 | # XDR definition: 25 | # struct nfs_fh3 { 26 | # opaque data; 27 | # }; 28 | def __init__(self, data=None): 29 | self.data = data 30 | 31 | def __repr__(self): 32 | out = [] 33 | if self.data is not None: 34 | out += ['data=%s' % repr(self.data)] 35 | return 'nfs_fh3(%s)' % ', '.join(out) 36 | 37 | 38 | class nfstime3: 39 | # XDR definition: 40 | # struct nfstime3 { 41 | # uint32 seconds; 42 | # uint32 nseconds; 43 | # }; 44 | def __init__(self, seconds=None, nseconds=None): 45 | self.seconds = seconds 46 | self.nseconds = nseconds 47 | 48 | def __repr__(self): 49 | out = [] 50 | if self.seconds is not None: 51 | out += ['seconds=%s' % repr(self.seconds)] 52 | if self.nseconds is not None: 53 | out += ['nseconds=%s' % repr(self.nseconds)] 54 | return 'nfstime3(%s)' % ', '.join(out) 55 | 56 | 57 | class fattr3: 58 | # XDR definition: 59 | # struct fattr3 { 60 | # ftype3 type; 61 | # uint32 mode; 62 | # uint32 nlink; 63 | # uint32 uid; 64 | # uint32 gid; 65 | # uint64 size; 66 | # uint64 used; 67 | # specdata3 rdev; 68 | # uint64 fsid; 69 | # uint64 fileid; 70 | # nfstime3 atime; 71 | # nfstime3 mtime; 72 | # nfstime3 ctime; 73 | # }; 74 | def __init__(self, type=None, mode=None, nlink=None, uid=None, gid=None, size=None, used=None, rdev=None, 75 | fsid=None, fileid=None, atime=None, mtime=None, ctime=None): 76 | self.type = type 77 | self.mode = mode 78 | self.nlink = nlink 79 | self.uid = uid 80 | self.gid = gid 81 | self.size = size 82 | self.used = used 83 | self.rdev = rdev 84 | self.fsid = fsid 85 | self.fileid = fileid 86 | self.atime = atime 87 | self.mtime = mtime 88 | self.ctime = ctime 89 | 90 | def __repr__(self): 91 | out = [] 92 | if self.type is not None: 93 | out += ['type=%s' % const.FTYPE3.get(self.type, self.type)] 94 | if self.mode is not None: 95 | out += ['mode=%s' % repr(self.mode)] 96 | if self.nlink is not None: 97 | out += ['nlink=%s' % repr(self.nlink)] 98 | if self.uid is not None: 99 | out += ['uid=%s' % repr(self.uid)] 100 | if self.gid is not None: 101 | out += ['gid=%s' % repr(self.gid)] 102 | if self.size is not None: 103 | out += ['size=%s' % repr(self.size)] 104 | if self.used is not None: 105 | out += ['used=%s' % repr(self.used)] 106 | if self.rdev is not None: 107 | out += ['rdev=%s' % repr(self.rdev)] 108 | if self.fsid is not None: 109 | out += ['fsid=%s' % repr(self.fsid)] 110 | if self.fileid is not None: 111 | out += ['fileid=%s' % repr(self.fileid)] 112 | if self.atime is not None: 113 | out += ['atime=%s' % repr(self.atime)] 114 | if self.mtime is not None: 115 | out += ['mtime=%s' % repr(self.mtime)] 116 | if self.ctime is not None: 117 | out += ['ctime=%s' % repr(self.ctime)] 118 | return 'fattr3(%s)' % ', '.join(out) 119 | 120 | 121 | class post_op_attr: 122 | # XDR definition: 123 | # union post_op_attr switch(bool present) { 124 | # case TRUE: 125 | # fattr3 attributes; 126 | # case FALSE: 127 | # void; 128 | # }; 129 | def __init__(self, present=None, attributes=None): 130 | self.present = present 131 | self.attributes = attributes 132 | 133 | def __repr__(self): 134 | out = [] 135 | if self.present is not None: 136 | out += ['present=%s' % repr(self.present)] 137 | if self.attributes is not None: 138 | out += ['attributes=%s' % repr(self.attributes)] 139 | return 'post_op_attr(%s)' % ', '.join(out) 140 | 141 | 142 | class wcc_attr: 143 | # XDR definition: 144 | # struct wcc_attr { 145 | # uint64 size; 146 | # nfstime3 mtime; 147 | # nfstime3 ctime; 148 | # }; 149 | def __init__(self, size=None, mtime=None, ctime=None): 150 | self.size = size 151 | self.mtime = mtime 152 | self.ctime = ctime 153 | 154 | def __repr__(self): 155 | out = [] 156 | if self.size is not None: 157 | out += ['size=%s' % repr(self.size)] 158 | if self.mtime is not None: 159 | out += ['mtime=%s' % repr(self.mtime)] 160 | if self.ctime is not None: 161 | out += ['ctime=%s' % repr(self.ctime)] 162 | return 'wcc_attr(%s)' % ', '.join(out) 163 | 164 | 165 | class pre_op_attr: 166 | # XDR definition: 167 | # union pre_op_attr switch(bool present) { 168 | # case TRUE: 169 | # wcc_attr attributes; 170 | # case FALSE: 171 | # void; 172 | # }; 173 | def __init__(self, present=None, attributes=None): 174 | self.present = present 175 | self.attributes = attributes 176 | 177 | def __repr__(self): 178 | out = [] 179 | if self.present is not None: 180 | out += ['present=%s' % repr(self.present)] 181 | if self.attributes is not None: 182 | out += ['attributes=%s' % repr(self.attributes)] 183 | return 'pre_op_attr(%s)' % ', '.join(out) 184 | 185 | 186 | class wcc_data: 187 | # XDR definition: 188 | # struct wcc_data { 189 | # pre_op_attr before; 190 | # post_op_attr after; 191 | # }; 192 | def __init__(self, before=None, after=None): 193 | self.before = before 194 | self.after = after 195 | 196 | def __repr__(self): 197 | out = [] 198 | if self.before is not None: 199 | out += ['before=%s' % repr(self.before)] 200 | if self.after is not None: 201 | out += ['after=%s' % repr(self.after)] 202 | return 'wcc_data(%s)' % ', '.join(out) 203 | 204 | 205 | class post_op_fh3: 206 | # XDR definition: 207 | # union post_op_fh3 switch(bool present) { 208 | # case TRUE: 209 | # nfs_fh3 handle; 210 | # case FALSE: 211 | # void; 212 | # }; 213 | def __init__(self, present=None, handle=None): 214 | self.present = present 215 | self.handle = handle 216 | 217 | def __repr__(self): 218 | out = [] 219 | if self.present is not None: 220 | out += ['present=%s' % repr(self.present)] 221 | if self.handle is not None: 222 | out += ['handle=%s' % repr(self.handle)] 223 | return 'post_op_fh3(%s)' % ', '.join(out) 224 | 225 | 226 | class set_uint32: 227 | # XDR definition: 228 | # union set_uint32 switch(bool set) { 229 | # case TRUE: 230 | # uint32 val; 231 | # default: 232 | # void; 233 | # }; 234 | def __init__(self, set=None, val=None): 235 | self.set = set 236 | self.val = val 237 | 238 | def __repr__(self): 239 | out = [] 240 | if self.set is not None: 241 | out += ['set=%s' % repr(self.set)] 242 | if self.val is not None: 243 | out += ['val=%s' % repr(self.val)] 244 | return 'set_uint32(%s)' % ', '.join(out) 245 | 246 | 247 | class set_uint64: 248 | # XDR definition: 249 | # union set_uint64 switch(bool set) { 250 | # case TRUE: 251 | # uint64 val; 252 | # default: 253 | # void; 254 | # }; 255 | def __init__(self, set=None, val=None): 256 | self.set = set 257 | self.val = val 258 | 259 | def __repr__(self): 260 | out = [] 261 | if self.set is not None: 262 | out += ['set=%s' % repr(self.set)] 263 | if self.val is not None: 264 | out += ['val=%s' % repr(self.val)] 265 | return 'set_uint64(%s)' % ', '.join(out) 266 | 267 | 268 | class set_time: 269 | # XDR definition: 270 | # union set_time switch(time_how set) { 271 | # case SET_TO_CLIENT_TIME: 272 | # nfstime3 time; 273 | # default: 274 | # void; 275 | # }; 276 | def __init__(self, set=None, time=None): 277 | self.set = set 278 | self.time = time 279 | 280 | def __repr__(self): 281 | out = [] 282 | if self.set is not None: 283 | out += ['set=%s' % const.time_how.get(self.set, self.set)] 284 | if self.time is not None: 285 | out += ['time=%s' % repr(self.time)] 286 | return 'set_time(%s)' % ', '.join(out) 287 | 288 | 289 | class sattr3: 290 | # XDR definition: 291 | # struct sattr3 { 292 | # set_uint32 mode; 293 | # set_uint32 uid; 294 | # set_uint32 gid; 295 | # set_uint64 size; 296 | # set_time atime; 297 | # set_time mtime; 298 | # }; 299 | def __init__(self, mode=None, uid=None, gid=None, size=None, atime=None, mtime=None): 300 | self.mode = mode 301 | self.uid = uid 302 | self.gid = gid 303 | self.size = size 304 | self.atime = atime 305 | self.mtime = mtime 306 | 307 | def __repr__(self): 308 | out = [] 309 | if self.mode is not None: 310 | out += ['mode=%s' % repr(self.mode)] 311 | if self.uid is not None: 312 | out += ['uid=%s' % repr(self.uid)] 313 | if self.gid is not None: 314 | out += ['gid=%s' % repr(self.gid)] 315 | if self.size is not None: 316 | out += ['size=%s' % repr(self.size)] 317 | if self.atime is not None: 318 | out += ['atime=%s' % repr(self.atime)] 319 | if self.mtime is not None: 320 | out += ['mtime=%s' % repr(self.mtime)] 321 | return 'sattr3(%s)' % ', '.join(out) 322 | 323 | 324 | class diropargs3: 325 | # XDR definition: 326 | # struct diropargs3 { 327 | # nfs_fh3 dir; 328 | # filename3 name; 329 | # }; 330 | def __init__(self, dir=None, name=None): 331 | self.dir = dir 332 | self.name = name 333 | 334 | def __repr__(self): 335 | out = [] 336 | if self.dir is not None: 337 | out += ['dir=%s' % repr(self.dir)] 338 | if self.name is not None: 339 | out += ['name=%s' % repr(self.name)] 340 | return 'diropargs3(%s)' % ', '.join(out) 341 | 342 | 343 | class diropres3ok: 344 | # XDR definition: 345 | # struct diropres3ok { 346 | # post_op_fh3 obj; 347 | # post_op_attr obj_attributes; 348 | # wcc_data dir_wcc; 349 | # }; 350 | def __init__(self, obj=None, obj_attributes=None, dir_wcc=None): 351 | self.obj = obj 352 | self.obj_attributes = obj_attributes 353 | self.dir_wcc = dir_wcc 354 | 355 | def __repr__(self): 356 | out = [] 357 | if self.obj is not None: 358 | out += ['obj=%s' % repr(self.obj)] 359 | if self.obj_attributes is not None: 360 | out += ['obj_attributes=%s' % repr(self.obj_attributes)] 361 | if self.dir_wcc is not None: 362 | out += ['dir_wcc=%s' % repr(self.dir_wcc)] 363 | return 'diropres3ok(%s)' % ', '.join(out) 364 | 365 | 366 | class diropres3: 367 | # XDR definition: 368 | # union diropres3 switch(nfsstat3 status) { 369 | # case NFS3_OK: 370 | # diropres3ok resok; 371 | # default: 372 | # wcc_data resfail; 373 | # }; 374 | def __init__(self, status=None, resok=None): 375 | self.status = status 376 | self.resok = resok 377 | 378 | def __repr__(self): 379 | out = [] 380 | if self.status is not None: 381 | out += ['status=%s' % const.NFSSTAT3.get(self.status, self.status)] 382 | if self.resok is not None: 383 | out += ['resok=%s' % repr(self.resok)] 384 | return 'diropres3(%s)' % ', '.join(out) 385 | 386 | 387 | class wccstat3: 388 | # XDR definition: 389 | # union wccstat3 switch(nfsstat3 status) { 390 | # case -1: 391 | # void; 392 | # default: 393 | # wcc_data wcc; 394 | # }; 395 | def __init__(self, status=None): 396 | self.status = status 397 | 398 | def __repr__(self): 399 | out = [] 400 | if self.status is not None: 401 | out += ['status=%s' % const.NFSSTAT3.get(self.status, self.status)] 402 | return 'wccstat3(%s)' % ', '.join(out) 403 | 404 | 405 | class getattr3res: 406 | # XDR definition: 407 | # union getattr3res switch(nfsstat3 status) { 408 | # case NFS3_OK: 409 | # fattr3 attributes; 410 | # default: 411 | # void; 412 | # }; 413 | def __init__(self, status=None, attributes=None): 414 | self.status = status 415 | self.attributes = attributes 416 | 417 | def __repr__(self): 418 | out = [] 419 | if self.status is not None: 420 | out += ['status=%s' % const.NFSSTAT3.get(self.status, self.status)] 421 | if self.attributes is not None: 422 | out += ['attributes=%s' % repr(self.attributes)] 423 | return 'getattr3res(%s)' % ', '.join(out) 424 | 425 | 426 | class sattrguard3: 427 | # XDR definition: 428 | # union sattrguard3 switch(bool check) { 429 | # case TRUE: 430 | # nfstime3 ctime; 431 | # case FALSE: 432 | # void; 433 | # }; 434 | def __init__(self, check=None, ctime=None): 435 | self.check = check 436 | self.ctime = ctime 437 | 438 | def __repr__(self): 439 | out = [] 440 | if self.check is not None: 441 | out += ['check=%s' % repr(self.check)] 442 | if self.ctime is not None: 443 | out += ['ctime=%s' % repr(self.ctime)] 444 | return 'sattrguard3(%s)' % ', '.join(out) 445 | 446 | 447 | class setattr3args: 448 | # XDR definition: 449 | # struct setattr3args { 450 | # nfs_fh3 object; 451 | # sattr3 new_attributes; 452 | # sattrguard3 guard; 453 | # }; 454 | def __init__(self, object=None, new_attributes=None, guard=None): 455 | self.object = object 456 | self.new_attributes = new_attributes 457 | self.guard = guard 458 | 459 | def __repr__(self): 460 | out = [] 461 | if self.object is not None: 462 | out += ['object=%s' % repr(self.object)] 463 | if self.new_attributes is not None: 464 | out += ['new_attributes=%s' % repr(self.new_attributes)] 465 | if self.guard is not None: 466 | out += ['guard=%s' % repr(self.guard)] 467 | return 'setattr3args(%s)' % ', '.join(out) 468 | 469 | 470 | class wcc_data3res: 471 | def __init__(self, category, status=None, wcc_data=None): 472 | self.category = str(category) or '' 473 | self.status = status 474 | self.wcc_data = wcc_data 475 | 476 | def __repr__(self): 477 | out = [] 478 | if self.status is not None: 479 | out += ['status=%s' % const.NFSSTAT3.get(self.status, self.status)] 480 | if self.wcc_data is not None: 481 | out += ['wcc_data=%s' % repr(self.wcc_data)] 482 | return self.category + '(%s)' % ', '.join(out) 483 | 484 | 485 | class lookup3resok: 486 | # XDR definition: 487 | # struct lookup3resok { 488 | # nfs_fh3 object; 489 | # post_op_attr obj_attributes; 490 | # post_op_attr dir_attributes; 491 | # }; 492 | def __init__(self, object=None, obj_attributes=None, dir_attributes=None): 493 | self.object = object 494 | self.obj_attributes = obj_attributes 495 | self.dir_attributes = dir_attributes 496 | 497 | def __repr__(self): 498 | out = [] 499 | if self.object is not None: 500 | out += ['object=%s' % repr(self.object)] 501 | if self.obj_attributes is not None: 502 | out += ['obj_attributes=%s' % repr(self.obj_attributes)] 503 | if self.dir_attributes is not None: 504 | out += ['dir_attributes=%s' % repr(self.dir_attributes)] 505 | return 'lookup3resok(%s)' % ', '.join(out) 506 | 507 | 508 | class lookup3res: 509 | # XDR definition: 510 | # union lookup3res switch(nfsstat3 status) { 511 | # case NFS3_OK: 512 | # lookup3resok resok; 513 | # default: 514 | # post_op_attr resfail; 515 | # }; 516 | def __init__(self, status=None, resok=None): 517 | self.status = status 518 | self.resok = resok 519 | 520 | def __repr__(self): 521 | out = [] 522 | if self.status is not None: 523 | out += ['status=%s' % const.NFSSTAT3.get(self.status, self.status)] 524 | if self.resok is not None: 525 | out += ['resok=%s' % repr(self.resok)] 526 | return 'lookup3res(%s)' % ', '.join(out) 527 | 528 | 529 | class access3args: 530 | # XDR definition: 531 | # struct access3args { 532 | # nfs_fh3 object; 533 | # uint32 access; 534 | # }; 535 | def __init__(self, object=None, access=None): 536 | self.object = object 537 | self.access = access 538 | 539 | def __repr__(self): 540 | out = [] 541 | if self.object is not None: 542 | out += ['object=%s' % repr(self.object)] 543 | if self.access is not None: 544 | out += ['access=%s' % repr(self.access)] 545 | return 'access3args(%s)' % ', '.join(out) 546 | 547 | 548 | class access3resok: 549 | # XDR definition: 550 | # struct access3resok { 551 | # post_op_attr obj_attributes; 552 | # uint32 access; 553 | # }; 554 | def __init__(self, obj_attributes=None, access=None): 555 | self.obj_attributes = obj_attributes 556 | self.access = access 557 | 558 | def __repr__(self): 559 | out = [] 560 | if self.obj_attributes is not None: 561 | out += ['obj_attributes=%s' % repr(self.obj_attributes)] 562 | if self.access is not None: 563 | out += ['access=%s' % repr(self.access)] 564 | return 'access3resok(%s)' % ', '.join(out) 565 | 566 | 567 | class access3res: 568 | # XDR definition: 569 | # union access3res switch(nfsstat3 status) { 570 | # case NFS3_OK: 571 | # access3resok resok; 572 | # default: 573 | # post_op_attr resfail; 574 | # }; 575 | def __init__(self, status=None, resok=None): 576 | self.status = status 577 | self.resok = resok 578 | 579 | def __repr__(self): 580 | out = [] 581 | if self.status is not None: 582 | out += ['status=%s' % const.NFSSTAT3.get(self.status, self.status)] 583 | if self.resok is not None: 584 | out += ['resok=%s' % repr(self.resok)] 585 | return 'access3res(%s)' % ', '.join(out) 586 | 587 | 588 | class readlink3resok: 589 | # XDR definition: 590 | # struct readlink3resok { 591 | # post_op_attr symlink_attributes; 592 | # nfspath3 data; 593 | # }; 594 | def __init__(self, symlink_attributes=None, data=None): 595 | self.symlink_attributes = symlink_attributes 596 | self.data = data 597 | 598 | def __repr__(self): 599 | out = [] 600 | if self.symlink_attributes is not None: 601 | out += ['symlink_attributes=%s' % repr(self.symlink_attributes)] 602 | if self.data is not None: 603 | out += ['data=%s' % repr(self.data)] 604 | return 'readlink3resok(%s)' % ', '.join(out) 605 | 606 | 607 | class readlink3res: 608 | # XDR definition: 609 | # union readlink3res switch(nfsstat3 status) { 610 | # case NFS3_OK: 611 | # readlink3resok resok; 612 | # default: 613 | # post_op_attr resfail; 614 | # }; 615 | def __init__(self, status=None, resok=None): 616 | self.status = status 617 | self.resok = resok 618 | 619 | def __repr__(self): 620 | out = [] 621 | if self.status is not None: 622 | out += ['status=%s' % const.NFSSTAT3.get(self.status, self.status)] 623 | if self.resok is not None: 624 | out += ['resok=%s' % repr(self.resok)] 625 | return 'readlink3res(%s)' % ', '.join(out) 626 | 627 | 628 | class read3args: 629 | # XDR definition: 630 | # struct read3args { 631 | # nfs_fh3 file; 632 | # uint64 offset; 633 | # uint32 count; 634 | # }; 635 | def __init__(self, file=None, offset=None, count=None): 636 | self.file = file 637 | self.offset = offset 638 | self.count = count 639 | 640 | def __repr__(self): 641 | out = [] 642 | if self.file is not None: 643 | out += ['file=%s' % repr(self.file)] 644 | if self.offset is not None: 645 | out += ['offset=%s' % repr(self.offset)] 646 | if self.count is not None: 647 | out += ['count=%s' % repr(self.count)] 648 | return 'read3args(%s)' % ', '.join(out) 649 | 650 | 651 | class read3resok: 652 | # XDR definition: 653 | # struct read3resok { 654 | # post_op_attr file_attributes; 655 | # uint32 count; 656 | # bool eof; 657 | # opaque data<>; 658 | # }; 659 | def __init__(self, file_attributes=None, count=None, eof=None, data=None): 660 | self.file_attributes = file_attributes 661 | self.count = count 662 | self.eof = eof 663 | self.data = data 664 | 665 | def __repr__(self): 666 | out = [] 667 | if self.file_attributes is not None: 668 | out += ['file_attributes=%s' % repr(self.file_attributes)] 669 | if self.count is not None: 670 | out += ['count=%s' % repr(self.count)] 671 | if self.eof is not None: 672 | out += ['eof=%s' % repr(self.eof)] 673 | if self.data is not None: 674 | out += ['data=%s' % repr(self.data)] 675 | return 'read3resok(%s)' % ', '.join(out) 676 | 677 | 678 | class read3res: 679 | # XDR definition: 680 | # union read3res switch(nfsstat3 status) { 681 | # case NFS3_OK: 682 | # read3resok resok; 683 | # default: 684 | # post_op_attr resfail; 685 | # }; 686 | def __init__(self, status=None, resok=None): 687 | self.status = status 688 | self.resok = resok 689 | 690 | def __repr__(self): 691 | out = [] 692 | if self.status is not None: 693 | out += ['status=%s' % const.NFSSTAT3.get(self.status, self.status)] 694 | if self.resok is not None: 695 | out += ['resok=%s' % repr(self.resok)] 696 | return 'read3res(%s)' % ', '.join(out) 697 | 698 | 699 | class write3args: 700 | # XDR definition: 701 | # struct write3args { 702 | # nfs_fh3 file; 703 | # uint64 offset; 704 | # uint32 count; 705 | # stable_how stable; 706 | # opaque data<>; 707 | # }; 708 | def __init__(self, file=None, offset=None, count=None, stable=None, data=None): 709 | self.file = file 710 | self.offset = offset 711 | self.count = count 712 | self.stable = stable 713 | self.data = data 714 | 715 | def __repr__(self): 716 | out = [] 717 | if self.file is not None: 718 | out += ['file=%s' % repr(self.file)] 719 | if self.offset is not None: 720 | out += ['offset=%s' % repr(self.offset)] 721 | if self.count is not None: 722 | out += ['count=%s' % repr(self.count)] 723 | if self.stable is not None: 724 | out += ['stable=%s' % const.STABLE_HOW.get(self.stable, self.stable)] 725 | if self.data is not None: 726 | out += ['data=%s' % repr(self.data)] 727 | return 'write3args(%s)' % ', '.join(out) 728 | 729 | 730 | class write3resok: 731 | # XDR definition: 732 | # struct write3resok { 733 | # wcc_data file_wcc; 734 | # uint32 count; 735 | # stable_how committed; 736 | # writeverf3 verf; 737 | # }; 738 | def __init__(self, file_wcc=None, count=None, committed=None, verf=None): 739 | self.file_wcc = file_wcc 740 | self.count = count 741 | self.committed = committed 742 | self.verf = verf 743 | 744 | def __repr__(self): 745 | out = [] 746 | if self.file_wcc is not None: 747 | out += ['file_wcc=%s' % repr(self.file_wcc)] 748 | if self.count is not None: 749 | out += ['count=%s' % repr(self.count)] 750 | if self.committed is not None: 751 | out += ['committed=%s' % const.STABLE_HOW.get(self.committed, self.committed)] 752 | if self.verf is not None: 753 | out += ['verf=%s' % repr(self.verf)] 754 | return 'write3resok(%s)' % ', '.join(out) 755 | 756 | 757 | class write3res: 758 | # XDR definition: 759 | # union write3res switch(nfsstat3 status) { 760 | # case NFS3_OK: 761 | # write3resok resok; 762 | # default: 763 | # wcc_data resfail; 764 | # }; 765 | def __init__(self, status=None, resok=None): 766 | self.status = status 767 | self.resok = resok 768 | 769 | def __repr__(self): 770 | out = [] 771 | if self.status is not None: 772 | out += ['status=%s' % const.NFSSTAT3.get(self.status, self.status)] 773 | if self.resok is not None: 774 | out += ['resok=%s' % repr(self.resok)] 775 | return 'write3res(%s)' % ', '.join(out) 776 | 777 | 778 | class createhow3: 779 | # XDR definition: 780 | # union createhow3 switch(createmode3 mode) { 781 | # case UNCHECKED: 782 | # case GUARDED: 783 | # sattr3 obj_attributes; 784 | # case EXCLUSIVE: 785 | # createverf3 verf; 786 | # }; 787 | def __init__(self, mode=None, obj_attributes=None, verf=None): 788 | self.mode = mode 789 | self.obj_attributes = obj_attributes 790 | self.verf = verf 791 | 792 | def __repr__(self): 793 | out = [] 794 | if self.mode is not None: 795 | out += ['mode=%s' % const.CREATEMODE3.get(self.mode, self.mode)] 796 | if self.obj_attributes is not None: 797 | out += ['obj_attributes=%s' % repr(self.obj_attributes)] 798 | if self.verf is not None: 799 | out += ['verf=%s' % repr(self.verf)] 800 | return 'createhow3(%s)' % ', '.join(out) 801 | 802 | 803 | class create3args: 804 | # XDR definition: 805 | # struct create3args { 806 | # diropargs3 where; 807 | # createhow3 how; 808 | # }; 809 | def __init__(self, where=None, how=None): 810 | self.where = where 811 | self.how = how 812 | 813 | def __repr__(self): 814 | out = [] 815 | if self.where is not None: 816 | out += ['where=%s' % repr(self.where)] 817 | if self.how is not None: 818 | out += ['how=%s' % repr(self.how)] 819 | return 'create3args(%s)' % ', '.join(out) 820 | 821 | 822 | class create3resok: 823 | # XDR definition: 824 | # struct CREATE3resok { 825 | # post_op_fh3 obj; 826 | # post_op_attr obj_attributes; 827 | # wcc_data dir_wcc; 828 | # }; 829 | def __init__(self, obj=None, obj_attributes=None, dir_wcc=None): 830 | self.obj = obj 831 | self.obj_attributes = obj_attributes 832 | self.dir_wcc = dir_wcc 833 | 834 | def __repr__(self): 835 | out = list() 836 | if self.obj is not None: 837 | out += ['obj=%s' % repr(self.obj)] 838 | if self.obj_attributes is not None: 839 | out += ['obj_attributes=%s' % repr(self.obj_attributes)] 840 | if self.dir_wcc is not None: 841 | out += ['dir_wcc=%s' % repr(self.dir_wcc)] 842 | return 'create3resok(%s)' % ', '.join(out) 843 | 844 | 845 | class create3res: 846 | # XDR definition: 847 | # union CREATE3res switch (nfsstat3 status) { 848 | # case NFS3_OK: 849 | # CREATE3resok resok; 850 | # default: 851 | # CREATE3resfail resfail; 852 | # }; 853 | def __init__(self, status=None, resok=None): 854 | self.status = status 855 | self.resok = resok 856 | 857 | def __repr__(self): 858 | out = list() 859 | if self.status is not None: 860 | out += ['status=%s' % const.NFSSTAT3.get(self.status, self.status)] 861 | if self.resok is not None: 862 | out += ['resok=%s' % repr(self.resok)] 863 | return 'create3res(%s)' % ', '.join(out) 864 | 865 | 866 | class mkdir3args: 867 | # XDR definition: 868 | # struct mkdir3args { 869 | # diropargs3 where; 870 | # sattr3 attributes; 871 | # }; 872 | def __init__(self, where=None, attributes=None): 873 | self.where = where 874 | self.attributes = attributes 875 | 876 | def __repr__(self): 877 | out = [] 878 | if self.where is not None: 879 | out += ['where=%s' % repr(self.where)] 880 | if self.attributes is not None: 881 | out += ['attributes=%s' % repr(self.attributes)] 882 | return 'mkdir3args(%s)' % ', '.join(out) 883 | 884 | 885 | class symlinkdata3: 886 | # XDR definition: 887 | # struct symlinkdata3 { 888 | # sattr3 symlink_attributes; 889 | # nfspath3 symlink_data; 890 | # }; 891 | def __init__(self, symlink_attributes=None, symlink_data=None): 892 | self.symlink_attributes = symlink_attributes 893 | self.symlink_data = symlink_data 894 | 895 | def __repr__(self): 896 | out = [] 897 | if self.symlink_attributes is not None: 898 | out += ['symlink_attributes=%s' % repr(self.symlink_attributes)] 899 | if self.symlink_data is not None: 900 | out += ['symlink_data=%s' % repr(self.symlink_data)] 901 | return 'symlinkdata3(%s)' % ', '.join(out) 902 | 903 | 904 | class symlink3args: 905 | # XDR definition: 906 | # struct symlink3args { 907 | # diropargs3 where; 908 | # symlinkdata3 symlink; 909 | # }; 910 | def __init__(self, where=None, symlink=None): 911 | self.where = where 912 | self.symlink = symlink 913 | 914 | def __repr__(self): 915 | out = [] 916 | if self.where is not None: 917 | out += ['where=%s' % repr(self.where)] 918 | if self.symlink is not None: 919 | out += ['symlink=%s' % repr(self.symlink)] 920 | return 'symlink3args(%s)' % ', '.join(out) 921 | 922 | 923 | class devicedata3: 924 | # XDR definition: 925 | # struct devicedata3 { 926 | # sattr3 dev_attributes; 927 | # specdata3 spec; 928 | # }; 929 | def __init__(self, dev_attributes=None, spec=None): 930 | self.dev_attributes = dev_attributes 931 | self.spec = spec 932 | 933 | def __repr__(self): 934 | out = [] 935 | if self.dev_attributes is not None: 936 | out += ['dev_attributes=%s' % repr(self.dev_attributes)] 937 | if self.spec is not None: 938 | out += ['spec=%s' % repr(self.spec)] 939 | return 'devicedata3(%s)' % ', '.join(out) 940 | 941 | 942 | class mknoddata3: 943 | # XDR definition: 944 | # union mknoddata3 switch(ftype3 type) { 945 | # case NF3CHR: 946 | # case NF3BLK: 947 | # devicedata3 device; 948 | # case NF3SOCK: 949 | # case NF3FIFO: 950 | # sattr3 pipe_attributes; 951 | # default: 952 | # void; 953 | # }; 954 | def __init__(self, type=None, device=None, pipe_attributes=None): 955 | self.type = type 956 | self.device = device 957 | self.pipe_attributes = pipe_attributes 958 | 959 | def __repr__(self): 960 | out = [] 961 | if self.type is not None: 962 | out += ['type=%s' % const.FTYPE3.get(self.type, self.type)] 963 | if self.device is not None: 964 | out += ['device=%s' % repr(self.device)] 965 | if self.pipe_attributes is not None: 966 | out += ['pipe_attributes=%s' % repr(self.pipe_attributes)] 967 | return 'mknoddata3(%s)' % ', '.join(out) 968 | 969 | 970 | class mknod3args: 971 | # XDR definition: 972 | # struct mknod3args { 973 | # diropargs3 where; 974 | # mknoddata3 what; 975 | # }; 976 | def __init__(self, where=None, what=None): 977 | self.where = where 978 | self.what = what 979 | 980 | def __repr__(self): 981 | out = [] 982 | if self.where is not None: 983 | out += ['where=%s' % repr(self.where)] 984 | if self.what is not None: 985 | out += ['what=%s' % repr(self.what)] 986 | return 'mknod3args(%s)' % ', '.join(out) 987 | 988 | 989 | class rename3args: 990 | # XDR definition: 991 | # struct rename3args { 992 | # diropargs3 from; 993 | # diropargs3 to; 994 | # }; 995 | def __init__(self, from_v=None, to=None): 996 | self.from_v = from_v 997 | self.to = to 998 | 999 | def __repr__(self): 1000 | out = [] 1001 | if self.from_v is not None: 1002 | out += ['from=%s' % repr(self.from_v)] 1003 | if self.to is not None: 1004 | out += ['to=%s' % repr(self.to)] 1005 | return 'rename3args(%s)' % ', '.join(out) 1006 | 1007 | 1008 | class rename3wcc: 1009 | # XDR definition: 1010 | # struct rename3wcc { 1011 | # wcc_data fromdir_wcc; 1012 | # wcc_data todir_wcc; 1013 | # }; 1014 | def __init__(self, fromdir_wcc=None, todir_wcc=None): 1015 | self.fromdir_wcc = fromdir_wcc 1016 | self.todir_wcc = todir_wcc 1017 | 1018 | def __repr__(self): 1019 | out = [] 1020 | if self.fromdir_wcc is not None: 1021 | out += ['fromdir_wcc=%s' % repr(self.fromdir_wcc)] 1022 | if self.todir_wcc is not None: 1023 | out += ['todir_wcc=%s' % repr(self.todir_wcc)] 1024 | return 'rename3wcc(%s)' % ', '.join(out) 1025 | 1026 | 1027 | class rename3res: 1028 | # XDR definition: 1029 | # union rename3res switch(nfsstat3 status) { 1030 | # case -1: 1031 | # void; 1032 | # default: 1033 | # rename3wcc res; 1034 | # }; 1035 | def __init__(self, status=None): 1036 | self.status = status 1037 | 1038 | def __repr__(self): 1039 | out = [] 1040 | if self.status is not None: 1041 | out += ['status=%s' % const.NFSSTAT3.get(self.status, self.status)] 1042 | return 'rename3res(%s)' % ', '.join(out) 1043 | 1044 | 1045 | class link3args: 1046 | # XDR definition: 1047 | # struct link3args { 1048 | # nfs_fh3 file; 1049 | # diropargs3 link; 1050 | # }; 1051 | def __init__(self, file=None, link=None): 1052 | self.file = file 1053 | self.link = link 1054 | 1055 | def __repr__(self): 1056 | out = [] 1057 | if self.file is not None: 1058 | out += ['file=%s' % repr(self.file)] 1059 | if self.link is not None: 1060 | out += ['link=%s' % repr(self.link)] 1061 | return 'link3args(%s)' % ', '.join(out) 1062 | 1063 | 1064 | class link3wcc: 1065 | # XDR definition: 1066 | # struct link3wcc { 1067 | # post_op_attr file_attributes; 1068 | # wcc_data linkdir_wcc; 1069 | # }; 1070 | def __init__(self, file_attributes=None, linkdir_wcc=None): 1071 | self.file_attributes = file_attributes 1072 | self.linkdir_wcc = linkdir_wcc 1073 | 1074 | def __repr__(self): 1075 | out = [] 1076 | if self.file_attributes is not None: 1077 | out += ['file_attributes=%s' % repr(self.file_attributes)] 1078 | if self.linkdir_wcc is not None: 1079 | out += ['linkdir_wcc=%s' % repr(self.linkdir_wcc)] 1080 | return 'link3wcc(%s)' % ', '.join(out) 1081 | 1082 | 1083 | class link3res: 1084 | # XDR definition: 1085 | # union link3res switch(nfsstat3 status) { 1086 | # case -1: 1087 | # void; 1088 | # default: 1089 | # link3wcc res; 1090 | # }; 1091 | def __init__(self, status=None): 1092 | self.status = status 1093 | 1094 | def __repr__(self): 1095 | out = [] 1096 | if self.status is not None: 1097 | out += ['status=%s' % const.NFSSTAT3.get(self.status, self.status)] 1098 | return 'link3res(%s)' % ', '.join(out) 1099 | 1100 | 1101 | class readdir3args: 1102 | # XDR definition: 1103 | # struct readdir3args { 1104 | # nfs_fh3 dir; 1105 | # uint64 cookie; 1106 | # cookieverf3 cookieverf; 1107 | # uint32 count; 1108 | # }; 1109 | def __init__(self, dir=None, cookie=None, cookieverf=None, count=None): 1110 | self.dir = dir 1111 | self.cookie = cookie 1112 | self.cookieverf = cookieverf 1113 | self.count = count 1114 | 1115 | def __repr__(self): 1116 | out = [] 1117 | if self.dir is not None: 1118 | out += ['dir=%s' % repr(self.dir)] 1119 | if self.cookie is not None: 1120 | out += ['cookie=%s' % repr(self.cookie)] 1121 | if self.cookieverf is not None: 1122 | out += ['cookieverf=%s' % repr(self.cookieverf)] 1123 | if self.count is not None: 1124 | out += ['count=%s' % repr(self.count)] 1125 | return 'readdir3args(%s)' % ', '.join(out) 1126 | 1127 | 1128 | class entry3: 1129 | # XDR definition: 1130 | # struct entry3 { 1131 | # uint64 fileid; 1132 | # filename3 name; 1133 | # uint64 cookie; 1134 | # entry3 nextentry<1>; 1135 | # }; 1136 | def __init__(self, fileid=None, name=None, cookie=None, nextentry=None): 1137 | self.fileid = fileid 1138 | self.name = name 1139 | self.cookie = cookie 1140 | self.nextentry = nextentry 1141 | 1142 | def __repr__(self): 1143 | out = [] 1144 | if self.fileid is not None: 1145 | out += ['fileid=%s' % repr(self.fileid)] 1146 | if self.name is not None: 1147 | out += ['name=%s' % repr(self.name)] 1148 | if self.cookie is not None: 1149 | out += ['cookie=%s' % repr(self.cookie)] 1150 | if self.nextentry is not None: 1151 | out += ['nextentry=%s' % repr(self.nextentry)] 1152 | return 'entry3(%s)' % ', '.join(out) 1153 | 1154 | 1155 | class dirlist3: 1156 | # XDR definition: 1157 | # struct dirlist3 { 1158 | # entry3 entries<1>; 1159 | # bool eof; 1160 | # }; 1161 | def __init__(self, entries=None, eof=None): 1162 | self.entries = entries 1163 | self.eof = eof 1164 | 1165 | def __repr__(self): 1166 | out = [] 1167 | if self.entries is not None: 1168 | out += ['entries=%s' % repr(self.entries)] 1169 | if self.eof is not None: 1170 | out += ['eof=%s' % repr(self.eof)] 1171 | return 'dirlist3(%s)' % ', '.join(out) 1172 | 1173 | 1174 | class readdir3resok: 1175 | # XDR definition: 1176 | # struct readdir3resok { 1177 | # post_op_attr dir_attributes; 1178 | # cookieverf3 cookieverf; 1179 | # dirlist3 reply; 1180 | # }; 1181 | def __init__(self, dir_attributes=None, cookieverf=None, reply=None): 1182 | self.dir_attributes = dir_attributes 1183 | self.cookieverf = cookieverf 1184 | self.reply = reply 1185 | 1186 | def __repr__(self): 1187 | out = [] 1188 | if self.dir_attributes is not None: 1189 | out += ['dir_attributes=%s' % repr(self.dir_attributes)] 1190 | if self.cookieverf is not None: 1191 | out += ['cookieverf=%s' % repr(self.cookieverf)] 1192 | if self.reply is not None: 1193 | out += ['reply=%s' % repr(self.reply)] 1194 | return 'readdir3resok(%s)' % ', '.join(out) 1195 | 1196 | 1197 | class readdir3res: 1198 | # XDR definition: 1199 | # union readdir3res switch(nfsstat3 status) { 1200 | # case NFS3_OK: 1201 | # readdir3resok resok; 1202 | # default: 1203 | # post_op_attr resfail; 1204 | # }; 1205 | def __init__(self, status=None, resok=None): 1206 | self.status = status 1207 | self.resok = resok 1208 | 1209 | def __repr__(self): 1210 | out = [] 1211 | if self.status is not None: 1212 | out += ['status=%s' % const.NFSSTAT3.get(self.status, self.status)] 1213 | if self.resok is not None: 1214 | out += ['resok=%s' % repr(self.resok)] 1215 | return 'readdir3res(%s)' % ', '.join(out) 1216 | 1217 | 1218 | class readdirplus3args: 1219 | # XDR definition: 1220 | # struct readdirplus3args { 1221 | # nfs_fh3 dir; 1222 | # uint64 cookie; 1223 | # cookieverf3 cookieverf; 1224 | # uint32 dircount; 1225 | # uint32 maxcount; 1226 | # }; 1227 | def __init__(self, dir=None, cookie=None, cookieverf=None, dircount=None, maxcount=None): 1228 | self.dir = dir 1229 | self.cookie = cookie 1230 | self.cookieverf = cookieverf 1231 | self.dircount = dircount 1232 | self.maxcount = maxcount 1233 | 1234 | def __repr__(self): 1235 | out = [] 1236 | if self.dir is not None: 1237 | out += ['dir=%s' % repr(self.dir)] 1238 | if self.cookie is not None: 1239 | out += ['cookie=%s' % repr(self.cookie)] 1240 | if self.cookieverf is not None: 1241 | out += ['cookieverf=%s' % repr(self.cookieverf)] 1242 | if self.dircount is not None: 1243 | out += ['dircount=%s' % repr(self.dircount)] 1244 | if self.maxcount is not None: 1245 | out += ['maxcount=%s' % repr(self.maxcount)] 1246 | return 'readdirplus3args(%s)' % ', '.join(out) 1247 | 1248 | 1249 | class entryplus3: 1250 | # XDR definition: 1251 | # struct entryplus3 { 1252 | # uint64 fileid; 1253 | # filename3 name; 1254 | # uint64 cookie; 1255 | # post_op_attr name_attributes; 1256 | # post_op_fh3 name_handle; 1257 | # entryplus3 nextentry<1>; 1258 | # }; 1259 | def __init__(self, fileid=None, name=None, cookie=None, name_attributes=None, name_handle=None, nextentry=None): 1260 | self.fileid = fileid 1261 | self.name = name 1262 | self.cookie = cookie 1263 | self.name_attributes = name_attributes 1264 | self.name_handle = name_handle 1265 | self.nextentry = nextentry 1266 | 1267 | def __repr__(self): 1268 | out = [] 1269 | if self.fileid is not None: 1270 | out += ['fileid=%s' % repr(self.fileid)] 1271 | if self.name is not None: 1272 | out += ['name=%s' % repr(self.name)] 1273 | if self.cookie is not None: 1274 | out += ['cookie=%s' % repr(self.cookie)] 1275 | if self.name_attributes is not None: 1276 | out += ['name_attributes=%s' % repr(self.name_attributes)] 1277 | if self.name_handle is not None: 1278 | out += ['name_handle=%s' % repr(self.name_handle)] 1279 | if self.nextentry is not None: 1280 | out += ['nextentry=%s' % repr(self.nextentry)] 1281 | return 'entryplus3(%s)' % ', '.join(out) 1282 | 1283 | 1284 | class dirlistplus3: 1285 | # XDR definition: 1286 | # struct dirlistplus3 { 1287 | # entryplus3 entries<1>; 1288 | # bool eof; 1289 | # }; 1290 | def __init__(self, entries=None, eof=None): 1291 | self.entries = entries 1292 | self.eof = eof 1293 | 1294 | def __repr__(self): 1295 | out = [] 1296 | if self.entries is not None: 1297 | out += ['entries=%s' % repr(self.entries)] 1298 | if self.eof is not None: 1299 | out += ['eof=%s' % repr(self.eof)] 1300 | return 'dirlistplus3(%s)' % ', '.join(out) 1301 | 1302 | 1303 | class readdirplus3resok: 1304 | # XDR definition: 1305 | # struct readdirplus3resok { 1306 | # post_op_attr dir_attributes; 1307 | # cookieverf3 cookieverf; 1308 | # dirlistplus3 reply; 1309 | # }; 1310 | def __init__(self, dir_attributes=None, cookieverf=None, reply=None): 1311 | self.dir_attributes = dir_attributes 1312 | self.cookieverf = cookieverf 1313 | self.reply = reply 1314 | 1315 | def __repr__(self): 1316 | out = [] 1317 | if self.dir_attributes is not None: 1318 | out += ['dir_attributes=%s' % repr(self.dir_attributes)] 1319 | if self.cookieverf is not None: 1320 | out += ['cookieverf=%s' % repr(self.cookieverf)] 1321 | if self.reply is not None: 1322 | out += ['reply=%s' % repr(self.reply)] 1323 | return 'readdirplus3resok(%s)' % ', '.join(out) 1324 | 1325 | 1326 | class readdirplus3res: 1327 | # XDR definition: 1328 | # union readdirplus3res switch(nfsstat3 status) { 1329 | # case NFS3_OK: 1330 | # readdirplus3resok resok; 1331 | # default: 1332 | # post_op_attr resfail; 1333 | # }; 1334 | def __init__(self, status=None, resok=None): 1335 | self.status = status 1336 | self.resok = resok 1337 | 1338 | def __repr__(self): 1339 | out = [] 1340 | if self.status is not None: 1341 | out += ['status=%s' % const.NFSSTAT3.get(self.status, self.status)] 1342 | if self.resok is not None: 1343 | out += ['resok=%s' % repr(self.resok)] 1344 | return 'readdirplus3res(%s)' % ', '.join(out) 1345 | 1346 | 1347 | class fsstat3resok: 1348 | # XDR definition: 1349 | # struct fsstat3resok { 1350 | # post_op_attr obj_attributes; 1351 | # uint64 tbytes; 1352 | # uint64 fbytes; 1353 | # uint64 abytes; 1354 | # uint64 tfiles; 1355 | # uint64 ffiles; 1356 | # uint64 afiles; 1357 | # uint32 invarsec; 1358 | # }; 1359 | def __init__(self, obj_attributes=None, tbytes=None, fbytes=None, abytes=None, tfiles=None, ffiles=None, 1360 | afiles=None, invarsec=None): 1361 | self.obj_attributes = obj_attributes 1362 | self.tbytes = tbytes 1363 | self.fbytes = fbytes 1364 | self.abytes = abytes 1365 | self.tfiles = tfiles 1366 | self.ffiles = ffiles 1367 | self.afiles = afiles 1368 | self.invarsec = invarsec 1369 | 1370 | def __repr__(self): 1371 | out = [] 1372 | if self.obj_attributes is not None: 1373 | out += ['obj_attributes=%s' % repr(self.obj_attributes)] 1374 | if self.tbytes is not None: 1375 | out += ['tbytes=%s' % repr(self.tbytes)] 1376 | if self.fbytes is not None: 1377 | out += ['fbytes=%s' % repr(self.fbytes)] 1378 | if self.abytes is not None: 1379 | out += ['abytes=%s' % repr(self.abytes)] 1380 | if self.tfiles is not None: 1381 | out += ['tfiles=%s' % repr(self.tfiles)] 1382 | if self.ffiles is not None: 1383 | out += ['ffiles=%s' % repr(self.ffiles)] 1384 | if self.afiles is not None: 1385 | out += ['afiles=%s' % repr(self.afiles)] 1386 | if self.invarsec is not None: 1387 | out += ['invarsec=%s' % repr(self.invarsec)] 1388 | return 'fsstat3resok(%s)' % ', '.join(out) 1389 | 1390 | 1391 | class fsstat3res: 1392 | # XDR definition: 1393 | # union fsstat3res switch(nfsstat3 status) { 1394 | # case NFS3_OK: 1395 | # fsstat3resok resok; 1396 | # default: 1397 | # post_op_attr resfail; 1398 | # }; 1399 | def __init__(self, status=None, resok=None): 1400 | self.status = status 1401 | self.resok = resok 1402 | 1403 | def __repr__(self): 1404 | out = [] 1405 | if self.status is not None: 1406 | out += ['status=%s' % const.NFSSTAT3.get(self.status, self.status)] 1407 | if self.resok is not None: 1408 | out += ['resok=%s' % repr(self.resok)] 1409 | return 'fsstat3res(%s)' % ', '.join(out) 1410 | 1411 | 1412 | class fsinfo3resok: 1413 | # XDR definition: 1414 | # struct fsinfo3resok { 1415 | # post_op_attr obj_attributes; 1416 | # uint32 rtmax; 1417 | # uint32 rtpref; 1418 | # uint32 rtmult; 1419 | # uint32 wtmax; 1420 | # uint32 wtpref; 1421 | # uint32 wtmult; 1422 | # uint32 dtpref; 1423 | # uint64 maxfilesize; 1424 | # nfstime3 time_delta; 1425 | # uint32 properties; 1426 | # }; 1427 | def __init__(self, obj_attributes=None, rtmax=None, rtpref=None, rtmult=None, wtmax=None, wtpref=None, 1428 | wtmult=None, dtpref=None, maxfilesize=None, time_delta=None, properties=None): 1429 | self.obj_attributes = obj_attributes 1430 | self.rtmax = rtmax 1431 | self.rtpref = rtpref 1432 | self.rtmult = rtmult 1433 | self.wtmax = wtmax 1434 | self.wtpref = wtpref 1435 | self.wtmult = wtmult 1436 | self.dtpref = dtpref 1437 | self.maxfilesize = maxfilesize 1438 | self.time_delta = time_delta 1439 | self.properties = properties 1440 | 1441 | def __repr__(self): 1442 | out = [] 1443 | if self.obj_attributes is not None: 1444 | out += ['obj_attributes=%s' % repr(self.obj_attributes)] 1445 | if self.rtmax is not None: 1446 | out += ['rtmax=%s' % repr(self.rtmax)] 1447 | if self.rtpref is not None: 1448 | out += ['rtpref=%s' % repr(self.rtpref)] 1449 | if self.rtmult is not None: 1450 | out += ['rtmult=%s' % repr(self.rtmult)] 1451 | if self.wtmax is not None: 1452 | out += ['wtmax=%s' % repr(self.wtmax)] 1453 | if self.wtpref is not None: 1454 | out += ['wtpref=%s' % repr(self.wtpref)] 1455 | if self.wtmult is not None: 1456 | out += ['wtmult=%s' % repr(self.wtmult)] 1457 | if self.dtpref is not None: 1458 | out += ['dtpref=%s' % repr(self.dtpref)] 1459 | if self.maxfilesize is not None: 1460 | out += ['maxfilesize=%s' % repr(self.maxfilesize)] 1461 | if self.time_delta is not None: 1462 | out += ['time_delta=%s' % repr(self.time_delta)] 1463 | if self.properties is not None: 1464 | out += ['properties=%s' % repr(self.properties)] 1465 | return 'fsinfo3resok(%s)' % ', '.join(out) 1466 | 1467 | 1468 | class fsinfo3res: 1469 | # XDR definition: 1470 | # union fsinfo3res switch(nfsstat3 status) { 1471 | # case NFS3_OK: 1472 | # fsinfo3resok resok; 1473 | # default: 1474 | # post_op_attr resfail; 1475 | # }; 1476 | def __init__(self, status=None, resok=None): 1477 | self.status = status 1478 | self.resok = resok 1479 | 1480 | def __repr__(self): 1481 | out = [] 1482 | if self.status is not None: 1483 | out += ['status=%s' % const.NFSSTAT3.get(self.status, self.status)] 1484 | if self.resok is not None: 1485 | out += ['resok=%s' % repr(self.resok)] 1486 | return 'fsinfo3res(%s)' % ', '.join(out) 1487 | 1488 | 1489 | class pathconf3resok: 1490 | # XDR definition: 1491 | # struct pathconf3resok { 1492 | # post_op_attr obj_attributes; 1493 | # uint32 linkmax; 1494 | # uint32 name_max; 1495 | # bool no_trunc; 1496 | # bool chown_restricted; 1497 | # bool case_insensitive; 1498 | # bool case_preserving; 1499 | # }; 1500 | def __init__(self, obj_attributes=None, linkmax=None, name_max=None, no_trunc=None, chown_restricted=None, 1501 | case_insensitive=None, case_preserving=None): 1502 | self.obj_attributes = obj_attributes 1503 | self.linkmax = linkmax 1504 | self.name_max = name_max 1505 | self.no_trunc = no_trunc 1506 | self.chown_restricted = chown_restricted 1507 | self.case_insensitive = case_insensitive 1508 | self.case_preserving = case_preserving 1509 | 1510 | def __repr__(self): 1511 | out = [] 1512 | if self.obj_attributes is not None: 1513 | out += ['obj_attributes=%s' % repr(self.obj_attributes)] 1514 | if self.linkmax is not None: 1515 | out += ['linkmax=%s' % repr(self.linkmax)] 1516 | if self.name_max is not None: 1517 | out += ['name_max=%s' % repr(self.name_max)] 1518 | if self.no_trunc is not None: 1519 | out += ['no_trunc=%s' % repr(self.no_trunc)] 1520 | if self.chown_restricted is not None: 1521 | out += ['chown_restricted=%s' % repr(self.chown_restricted)] 1522 | if self.case_insensitive is not None: 1523 | out += ['case_insensitive=%s' % repr(self.case_insensitive)] 1524 | if self.case_preserving is not None: 1525 | out += ['case_preserving=%s' % repr(self.case_preserving)] 1526 | return 'pathconf3resok(%s)' % ', '.join(out) 1527 | 1528 | 1529 | class pathconf3res: 1530 | # XDR definition: 1531 | # union pathconf3res switch(nfsstat3 status) { 1532 | # case NFS3_OK: 1533 | # pathconf3resok resok; 1534 | # default: 1535 | # post_op_attr resfail; 1536 | # }; 1537 | def __init__(self, status=None, resok=None): 1538 | self.status = status 1539 | self.resok = resok 1540 | 1541 | def __repr__(self): 1542 | out = [] 1543 | if self.status is not None: 1544 | out += ['status=%s' % const.NFSSTAT3.get(self.status, self.status)] 1545 | if self.resok is not None: 1546 | out += ['resok=%s' % repr(self.resok)] 1547 | return 'pathconf3res(%s)' % ', '.join(out) 1548 | 1549 | 1550 | class commit3args: 1551 | # XDR definition: 1552 | # struct commit3args { 1553 | # nfs_fh3 file; 1554 | # uint64 offset; 1555 | # uint32 count; 1556 | # }; 1557 | def __init__(self, file=None, offset=None, count=None): 1558 | self.file = file 1559 | self.offset = offset 1560 | self.count = count 1561 | 1562 | def __repr__(self): 1563 | out = [] 1564 | if self.file is not None: 1565 | out += ['file=%s' % repr(self.file)] 1566 | if self.offset is not None: 1567 | out += ['offset=%s' % repr(self.offset)] 1568 | if self.count is not None: 1569 | out += ['count=%s' % repr(self.count)] 1570 | return 'commit3args(%s)' % ', '.join(out) 1571 | 1572 | 1573 | class commit3resok: 1574 | # XDR definition: 1575 | # struct commit3resok { 1576 | # wcc_data file_wcc; 1577 | # writeverf3 verf; 1578 | # }; 1579 | def __init__(self, file_wcc=None, verf=None): 1580 | self.file_wcc = file_wcc 1581 | self.verf = verf 1582 | 1583 | def __repr__(self): 1584 | out = [] 1585 | if self.file_wcc is not None: 1586 | out += ['file_wcc=%s' % repr(self.file_wcc)] 1587 | if self.verf is not None: 1588 | out += ['verf=%s' % repr(self.verf)] 1589 | return 'commit3resok(%s)' % ', '.join(out) 1590 | 1591 | 1592 | class commit3res: 1593 | # XDR definition: 1594 | # union commit3res switch(nfsstat3 status) { 1595 | # case NFS3_OK: 1596 | # commit3resok resok; 1597 | # default: 1598 | # wcc_data resfail; 1599 | # }; 1600 | def __init__(self, status=None, resok=None): 1601 | self.status = status 1602 | self.resok = resok 1603 | 1604 | def __repr__(self): 1605 | out = [] 1606 | if self.status is not None: 1607 | out += ['status=%s' % const.NFSSTAT3.get(self.status, self.status)] 1608 | if self.resok is not None: 1609 | out += ['resok=%s' % repr(self.resok)] 1610 | return 'commit3res(%s)' % ', '.join(out) 1611 | 1612 | 1613 | class setaclargs: 1614 | # XDR definition: 1615 | # struct setaclargs { 1616 | # diropargs3 dargs; 1617 | # write3args wargs; 1618 | # }; 1619 | def __init__(self, dargs=None, wargs=None): 1620 | self.dargs = dargs 1621 | self.wargs = wargs 1622 | 1623 | def __repr__(self): 1624 | out = [] 1625 | if self.dargs is not None: 1626 | out += ['dargs=%s' % repr(self.dargs)] 1627 | if self.wargs is not None: 1628 | out += ['wargs=%s' % repr(self.wargs)] 1629 | return 'setaclargs(%s)' % ', '.join(out) 1630 | 1631 | 1632 | class mountres3_ok: 1633 | # XDR definition: 1634 | # struct mountres3_ok { 1635 | # fhandle3 fhandle; 1636 | # int auth_flavors<>; 1637 | # }; 1638 | def __init__(self, fhandle=None, auth_flavors=None): 1639 | self.fhandle = fhandle 1640 | self.auth_flavors = auth_flavors 1641 | 1642 | def __repr__(self): 1643 | out = [] 1644 | if self.fhandle is not None: 1645 | out += ['fhandle=%s' % repr(self.fhandle)] 1646 | if self.auth_flavors is not None: 1647 | out += ['auth_flavors=%s' % repr(self.auth_flavors)] 1648 | return 'mountres3_ok(%s)' % ', '.join(out) 1649 | 1650 | 1651 | class mountres3: 1652 | # XDR definition: 1653 | # union mountres3 switch(mountstat3 fhs_status) { 1654 | # case MNT3_OK: 1655 | # mountres3_ok mountinfo; 1656 | # default: 1657 | # void; 1658 | # }; 1659 | def __init__(self, fhs_status=None, mountinfo=None): 1660 | self.status = fhs_status 1661 | self.mountinfo = mountinfo 1662 | 1663 | def __repr__(self): 1664 | out = [] 1665 | if self.status is not None: 1666 | out += ['fhs_status=%s' % const.MOUNTSTAT3.get(self.status, self.status)] 1667 | if self.mountinfo is not None: 1668 | out += ['mountinfo=%s' % repr(self.mountinfo)] 1669 | return 'mountres3(%s)' % ', '.join(out) 1670 | 1671 | 1672 | class mountbody: 1673 | # XDR definition: 1674 | # struct mountbody { 1675 | # name ml_hostname; 1676 | # dirpath ml_directory; 1677 | # mountlist ml_next; 1678 | # }; 1679 | def __init__(self, ml_hostname=None, ml_directory=None, ml_next=None): 1680 | self.ml_hostname = ml_hostname 1681 | self.ml_directory = ml_directory 1682 | self.ml_next = ml_next 1683 | 1684 | def __repr__(self): 1685 | out = [] 1686 | if self.ml_hostname is not None: 1687 | out += ['ml_hostname=%s' % repr(self.ml_hostname)] 1688 | if self.ml_directory is not None: 1689 | out += ['ml_directory=%s' % repr(self.ml_directory)] 1690 | if self.ml_next is not None: 1691 | out += ['ml_next=%s' % repr(self.ml_next)] 1692 | return 'mountbody(%s)' % ', '.join(out) 1693 | 1694 | 1695 | class groupnode: 1696 | # XDR definition: 1697 | # struct groupnode { 1698 | # name gr_name; 1699 | # groups gr_next; 1700 | # }; 1701 | def __init__(self, gr_name=None, gr_next=None): 1702 | self.gr_name = gr_name 1703 | self.gr_next = gr_next 1704 | 1705 | def __repr__(self): 1706 | out = [] 1707 | if self.gr_name is not None: 1708 | out += ['gr_name=%s' % repr(self.gr_name)] 1709 | if self.gr_next is not None: 1710 | out += ['gr_next=%s' % repr(self.gr_next)] 1711 | return 'groupnode(%s)' % ', '.join(out) 1712 | 1713 | 1714 | class exportnode: 1715 | # XDR definition: 1716 | # struct exportnode { 1717 | # dirpath ex_dir; 1718 | # groups ex_groups; 1719 | # exports ex_next; 1720 | # }; 1721 | def __init__(self, ex_dir=None, ex_groups=None, ex_next=None): 1722 | self.ex_dir = ex_dir 1723 | self.ex_groups = ex_groups 1724 | self.ex_next = ex_next 1725 | 1726 | def __repr__(self): 1727 | out = [] 1728 | if self.ex_dir is not None: 1729 | out += ['ex_dir=%s' % repr(self.ex_dir)] 1730 | if self.ex_groups is not None: 1731 | out += ['ex_groups=%s' % repr(self.ex_groups)] 1732 | if self.ex_next is not None: 1733 | out += ['ex_next=%s' % repr(self.ex_next)] 1734 | return 'exportnode(%s)' % ', '.join(out) 1735 | -------------------------------------------------------------------------------- /pyNfsClient/utils.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | # Useful for very coarse version differentiation. 4 | PY2 = sys.version_info[0] == 2 5 | PY3 = sys.version_info[0] == 3 6 | PY36 = sys.version_info[0:2] >= (3, 6) 7 | 8 | # long type vary with python versions 9 | if PY3: 10 | LONG = int 11 | else: 12 | LONG = long 13 | 14 | 15 | # convert string to bytes 16 | def str_to_bytes(str_v): 17 | if PY3: 18 | return str(str_v).encode() 19 | else: 20 | return bytes(str_v) 21 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [bdist_wheel] 2 | universal = 1 3 | 4 | [metadata] 5 | license_file = LICENSE -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Copyright (C) 2019 Cooper Yang 4 | # 5 | # This file is part of pyNfsClient. 6 | # 7 | # NfsClient is free software; you can redistribute it and/or modify it under the 8 | # terms of the MIT License. 9 | # 10 | # NfsClient is distributed in the hope that it will be useful, but WITHOUT ANY 11 | # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 12 | # A PARTICULAR PURPOSE. See the MIT License for more details. 13 | 14 | import os 15 | from setuptools import setup 16 | 17 | here = os.path.abspath(os.path.dirname(__file__)) 18 | 19 | about = dict() 20 | with open(os.path.join(here, "pyNfsClient", "__info__.py"), "r") as fp: 21 | exec(fp.read(), about) 22 | 23 | with open("README.rst", encoding="utf-8") as f: 24 | readme = f.read() 25 | 26 | with open("HISTORY.md", encoding="utf-8") as f: 27 | history = f.read() 28 | 29 | setup( 30 | name=about["__title__"], 31 | version=about["__version__"], 32 | description=about["__description__"], 33 | long_description=readme, 34 | long_description_content_type='text/x-rst', 35 | author=about["__author__"], 36 | author_email=about["__author_email__"], 37 | license="MIT", 38 | platforms='any', 39 | url=about["__url__"], 40 | packages=["pyNfsClient"], 41 | python_requires=">=2.7", 42 | keywords="RPC NFS struct", 43 | classifiers=[ 44 | 'Development Status :: 3 - Alpha', 45 | 'Intended Audience :: Developers', 46 | 'License :: OSI Approved :: MIT License', 47 | 'Operating System :: OS Independent', 48 | 'Topic :: System :: Filesystems', 49 | 'Topic :: Software Development :: Libraries :: Python Modules', 50 | 'Natural Language :: English', 51 | 'Programming Language :: Python :: 2.7', 52 | 'Programming Language :: Python :: 3.6', 53 | 'Programming Language :: Python :: 3.7', 54 | ], 55 | ) 56 | --------------------------------------------------------------------------------