first commit

This commit is contained in:
Stefan Hacker
2026-04-03 09:38:48 +02:00
commit 37ad745546
47450 changed files with 3120798 additions and 0 deletions
+110
View File
@@ -0,0 +1,110 @@
import { Reader } from '@jsonjoy.com/buffers/lib/Reader';
import { XdrDecoder } from '../../xdr/XdrDecoder';
import * as msg from './messages';
export declare class Nfsv4Decoder {
protected readonly xdr: XdrDecoder;
constructor(reader?: Reader);
decodeCompound(reader: Reader, isRequest: boolean): msg.Nfsv4CompoundRequest | msg.Nfsv4CompoundResponse | undefined;
decodeCompoundRequest(reader: Reader): msg.Nfsv4CompoundRequest;
decodeCompoundResponse(reader: Reader): msg.Nfsv4CompoundResponse;
private decodeRequest;
private decodeResponse;
private readFh;
private readVerifier;
private readStateid;
private readBitmap;
private readFattr;
private readChangeInfo;
private readClientAddr;
private readCbClient;
private readClientId;
private readOpenOwner;
private readLockOwner;
private readOpenToLockOwner;
private readLockOwnerInfo;
private readOpenClaim;
private readOpenHow;
private readOpenDelegation;
private readAce;
private readSecInfoFlavor;
private decodeAccessResponse;
private decodeCloseRequest;
private decodeCloseResponse;
private decodeCommitResponse;
private decodeCreateRequest;
private decodeCreateResponse;
private decodeDelegpurgeResponse;
private decodeDelegreturnResponse;
private decodeGetattrRequest;
private decodeGetattrResponse;
private decodeGetfhRequest;
private decodeGetfhResponse;
private decodeLinkRequest;
private decodeLinkResponse;
private decodeLockRequest;
private decodeLockResponse;
private decodeLocktRequest;
private decodeLocktResponse;
private decodeLockuRequest;
private decodeLockuResponse;
private decodeLookupRequest;
private decodeLookupResponse;
private decodeLookuppRequest;
private decodeLookuppResponse;
private decodeNverifyRequest;
private decodeNverifyResponse;
private decodeOpenRequest;
private decodeOpenResponse;
private decodeOpenattrRequest;
private decodeOpenattrResponse;
private decodeOpenConfirmRequest;
private decodeOpenConfirmResponse;
private decodeOpenDowngradeRequest;
private decodeOpenDowngradeResponse;
private decodePutfhRequest;
private decodePutfhResponse;
private decodePutrootfhResponse;
private decodeReadRequest;
private decodeReadResponse;
private decodeReaddirRequest;
private decodeReaddirResponse;
private decodeReadlinkRequest;
private decodeReadlinkResponse;
private decodeRemoveRequest;
private decodeRemoveResponse;
private decodeRenameRequest;
private decodeRenameResponse;
private decodeRenewRequest;
private decodeRenewResponse;
private decodeRestorefhRequest;
private decodeRestorefhResponse;
private decodeSavefhRequest;
private decodeSavefhResponse;
private decodeSecinfoRequest;
private decodeSecinfoResponse;
private decodeSetattrRequest;
private decodeSetattrResponse;
private decodeSetclientidRequest;
private decodeSetclientidResponse;
private decodeSetclientidConfirmRequest;
private decodeSetclientidConfirmResponse;
private decodeVerifyRequest;
private decodeVerifyResponse;
private decodeWriteRequest;
private decodeWriteResponse;
private decodeReleaseLockOwnerRequest;
private decodeReleaseLockOwnerResponse;
private decodeIllegalRequest;
private decodeIllegalResponse;
decodeCbCompound(reader: Reader, isRequest: boolean): msg.Nfsv4CbCompoundRequest | msg.Nfsv4CbCompoundResponse | undefined;
private decodeCbCompoundRequest;
private decodeCbCompoundResponse;
private decodeCbRequest;
private decodeCbResponse;
private decodeCbGetattrRequest;
private decodeCbGetattrResponse;
private decodeCbRecallRequest;
private decodeCbRecallResponse;
private decodeCbIllegalRequest;
private decodeCbIllegalResponse;
}
+966
View File
@@ -0,0 +1,966 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Nfsv4Decoder = void 0;
const tslib_1 = require("tslib");
const Reader_1 = require("@jsonjoy.com/buffers/lib/Reader");
const XdrDecoder_1 = require("../../xdr/XdrDecoder");
const errors_1 = require("./errors");
const msg = tslib_1.__importStar(require("./messages"));
const structs = tslib_1.__importStar(require("./structs"));
class Nfsv4Decoder {
constructor(reader = new Reader_1.Reader()) {
this.xdr = new XdrDecoder_1.XdrDecoder(reader);
}
decodeCompound(reader, isRequest) {
if (isRequest) {
return this.decodeCompoundRequest(reader);
}
else {
return this.decodeCompoundResponse(reader);
}
}
decodeCompoundRequest(reader) {
const xdr = this.xdr;
xdr.reader = reader;
const tag = xdr.readString();
const minorversion = xdr.readUnsignedInt();
const argarray = [];
const count = xdr.readUnsignedInt();
for (let i = 0; i < count; i++) {
const op = xdr.readUnsignedInt();
const request = this.decodeRequest(op);
if (request)
argarray.push(request);
}
return new msg.Nfsv4CompoundRequest(tag, minorversion, argarray);
}
decodeCompoundResponse(reader) {
const xdr = this.xdr;
xdr.reader = reader;
const status = xdr.readUnsignedInt();
const tag = xdr.readString();
const resarray = [];
const count = xdr.readUnsignedInt();
for (let i = 0; i < count; i++) {
const op = xdr.readUnsignedInt();
const response = this.decodeResponse(op);
if (response)
resarray.push(response);
}
return new msg.Nfsv4CompoundResponse(status, tag, resarray);
}
decodeRequest(op) {
const xdr = this.xdr;
switch (op) {
case 3:
return msg.Nfsv4AccessRequest.decode(xdr);
case 4:
return msg.Nfsv4CloseRequest.decode(xdr);
case 5:
return msg.Nfsv4CommitRequest.decode(xdr);
case 6:
return this.decodeCreateRequest();
case 7:
return msg.Nfsv4DelegpurgeRequest.decode(xdr);
case 8:
return msg.Nfsv4DelegreturnRequest.decode(xdr);
case 9:
return this.decodeGetattrRequest();
case 10:
return this.decodeGetfhRequest();
case 11:
return this.decodeLinkRequest();
case 12:
return this.decodeLockRequest();
case 13:
return this.decodeLocktRequest();
case 14:
return this.decodeLockuRequest();
case 15:
return this.decodeLookupRequest();
case 16:
return this.decodeLookuppRequest();
case 17:
return this.decodeNverifyRequest();
case 18:
return this.decodeOpenRequest();
case 19:
return this.decodeOpenattrRequest();
case 20:
return this.decodeOpenConfirmRequest();
case 21:
return this.decodeOpenDowngradeRequest();
case 22:
return this.decodePutfhRequest();
case 23:
return new msg.Nfsv4PutpubfhRequest();
case 24:
return new msg.Nfsv4PutrootfhRequest();
case 25:
return this.decodeReadRequest();
case 26:
return this.decodeReaddirRequest();
case 27:
return this.decodeReadlinkRequest();
case 28:
return this.decodeRemoveRequest();
case 29:
return this.decodeRenameRequest();
case 30:
return this.decodeRenewRequest();
case 31:
return this.decodeRestorefhRequest();
case 32:
return new msg.Nfsv4SavefhRequest();
case 33:
return this.decodeSecinfoRequest();
case 34:
return this.decodeSetattrRequest();
case 35:
return this.decodeSetclientidRequest();
case 36:
return this.decodeSetclientidConfirmRequest();
case 37:
return this.decodeVerifyRequest();
case 38:
return this.decodeWriteRequest();
case 39:
return this.decodeReleaseLockOwnerRequest();
case 10044:
return this.decodeIllegalRequest();
default:
return this.decodeIllegalRequest();
}
}
decodeResponse(op) {
const xdr = this.xdr;
switch (op) {
case 3:
return this.decodeAccessResponse();
case 4:
return this.decodeCloseResponse();
case 5:
return this.decodeCommitResponse();
case 6:
return this.decodeCreateResponse();
case 7:
return this.decodeDelegpurgeResponse();
case 8:
return this.decodeDelegreturnResponse();
case 9:
return this.decodeGetattrResponse();
case 10:
return this.decodeGetfhResponse();
case 11:
return this.decodeLinkResponse();
case 12:
return this.decodeLockResponse();
case 13:
return this.decodeLocktResponse();
case 14:
return this.decodeLockuResponse();
case 15:
return this.decodeLookupResponse();
case 16:
return this.decodeLookuppResponse();
case 17:
return this.decodeNverifyResponse();
case 18:
return this.decodeOpenResponse();
case 19:
return this.decodeOpenattrResponse();
case 20:
return this.decodeOpenConfirmResponse();
case 21:
return this.decodeOpenDowngradeResponse();
case 22:
return this.decodePutfhResponse();
case 23:
return msg.Nfsv4PutpubfhResponse.decode(xdr);
case 24:
return this.decodePutrootfhResponse();
case 25:
return this.decodeReadResponse();
case 26:
return this.decodeReaddirResponse();
case 27:
return this.decodeReadlinkResponse();
case 28:
return this.decodeRemoveResponse();
case 29:
return this.decodeRenameResponse();
case 30:
return this.decodeRenewResponse();
case 31:
return this.decodeRestorefhResponse();
case 32:
return this.decodeSavefhResponse();
case 33:
return this.decodeSecinfoResponse();
case 34:
return this.decodeSetattrResponse();
case 35:
return this.decodeSetclientidResponse();
case 36:
return this.decodeSetclientidConfirmResponse();
case 37:
return this.decodeVerifyResponse();
case 38:
return this.decodeWriteResponse();
case 39:
return this.decodeReleaseLockOwnerResponse();
case 10044:
return this.decodeIllegalResponse();
default:
return this.decodeIllegalResponse();
}
}
readFh() {
const data = this.xdr.readVarlenOpaque();
return new structs.Nfsv4Fh(data);
}
readVerifier() {
const data = this.xdr.readOpaque(8);
return new structs.Nfsv4Verifier(data);
}
readStateid() {
return structs.Nfsv4Stateid.decode(this.xdr);
}
readBitmap() {
const xdr = this.xdr;
const count = xdr.readUnsignedInt();
if (count > 8)
throw 10036;
const mask = [];
for (let i = 0; i < count; i++)
mask.push(xdr.readUnsignedInt());
return new structs.Nfsv4Bitmap(mask);
}
readFattr() {
const attrmask = this.readBitmap();
const attrVals = this.xdr.readVarlenOpaque();
return new structs.Nfsv4Fattr(attrmask, attrVals);
}
readChangeInfo() {
const xdr = this.xdr;
const atomic = xdr.readBoolean();
const before = xdr.readUnsignedHyper();
const after = xdr.readUnsignedHyper();
return new structs.Nfsv4ChangeInfo(atomic, before, after);
}
readClientAddr() {
const xdr = this.xdr;
const rNetid = xdr.readString();
const rAddr = xdr.readString();
return new structs.Nfsv4ClientAddr(rNetid, rAddr);
}
readCbClient() {
const cbProgram = this.xdr.readUnsignedInt();
const cbLocation = this.readClientAddr();
return new structs.Nfsv4CbClient(cbProgram, cbLocation);
}
readClientId() {
const verifier = this.readVerifier();
const id = this.xdr.readVarlenOpaque();
return new structs.Nfsv4ClientId(verifier, id);
}
readOpenOwner() {
const xdr = this.xdr;
const clientid = xdr.readUnsignedHyper();
const owner = xdr.readVarlenOpaque();
return new structs.Nfsv4OpenOwner(clientid, owner);
}
readLockOwner() {
const xdr = this.xdr;
const clientid = xdr.readUnsignedHyper();
const owner = xdr.readVarlenOpaque();
return new structs.Nfsv4LockOwner(clientid, owner);
}
readOpenToLockOwner() {
const xdr = this.xdr;
const openSeqid = xdr.readUnsignedInt();
const openStateid = this.readStateid();
const lockSeqid = xdr.readUnsignedInt();
const lockOwner = this.readLockOwner();
return new structs.Nfsv4OpenToLockOwner(openSeqid, openStateid, lockSeqid, lockOwner);
}
readLockOwnerInfo() {
const xdr = this.xdr;
const newLockOwner = xdr.readBoolean();
if (newLockOwner) {
const openToLockOwner = this.readOpenToLockOwner();
return new structs.Nfsv4LockOwnerInfo(true, new structs.Nfsv4LockNewOwner(openToLockOwner));
}
else {
const lockStateid = this.readStateid();
const lockSeqid = xdr.readUnsignedInt();
return new structs.Nfsv4LockOwnerInfo(false, new structs.Nfsv4LockExistingOwner(lockStateid, lockSeqid));
}
}
readOpenClaim() {
const xdr = this.xdr;
const claimType = xdr.readUnsignedInt();
switch (claimType) {
case 0: {
const file = xdr.readString();
return new structs.Nfsv4OpenClaim(claimType, new structs.Nfsv4OpenClaimNull(file));
}
case 1: {
const delegateType = xdr.readUnsignedInt();
return new structs.Nfsv4OpenClaim(claimType, new structs.Nfsv4OpenClaimPrevious(delegateType));
}
case 2: {
const delegateStateid = this.readStateid();
const file = xdr.readString();
return new structs.Nfsv4OpenClaim(claimType, new structs.Nfsv4OpenClaimDelegateCur(delegateStateid, file));
}
case 3: {
const file = xdr.readString();
return new structs.Nfsv4OpenClaim(claimType, new structs.Nfsv4OpenClaimDelegatePrev(file));
}
default:
throw new errors_1.Nfsv4DecodingError(`Unknown open claim type: ${claimType}`);
}
}
readOpenHow() {
const xdr = this.xdr;
const opentype = xdr.readUnsignedInt();
if (opentype === 0)
return new structs.Nfsv4OpenHow(opentype);
const mode = xdr.readUnsignedInt();
switch (mode) {
case 0:
case 1: {
const createattrs = this.readFattr();
return new structs.Nfsv4OpenHow(opentype, new structs.Nfsv4CreateHow(mode, new structs.Nfsv4CreateAttrs(createattrs)));
}
case 2: {
const createverf = this.readVerifier();
return new structs.Nfsv4OpenHow(opentype, new structs.Nfsv4CreateHow(mode, new structs.Nfsv4CreateVerf(createverf)));
}
default:
throw new errors_1.Nfsv4DecodingError(`Unknown create mode: ${mode}`);
}
}
readOpenDelegation() {
const xdr = this.xdr;
const delegationType = xdr.readUnsignedInt();
switch (delegationType) {
case 0:
return new structs.Nfsv4OpenDelegation(delegationType);
case 1: {
const stateid = this.readStateid();
const recall = xdr.readBoolean();
const aceCount = xdr.readUnsignedInt();
const permissions = [];
for (let i = 0; i < aceCount; i++) {
permissions.push(this.readAce());
}
return new structs.Nfsv4OpenDelegation(delegationType, new structs.Nfsv4OpenReadDelegation(stateid, recall, permissions));
}
case 2: {
const stateid = this.readStateid();
const recall = xdr.readBoolean();
const spaceLimit = xdr.readUnsignedHyper();
const aceCount = xdr.readUnsignedInt();
const permissions = [];
for (let i = 0; i < aceCount; i++) {
permissions.push(this.readAce());
}
return new structs.Nfsv4OpenDelegation(delegationType, new structs.Nfsv4OpenWriteDelegation(stateid, recall, spaceLimit, permissions));
}
default:
throw new errors_1.Nfsv4DecodingError(`Unknown delegation type: ${delegationType}`);
}
}
readAce() {
const xdr = this.xdr;
const type = xdr.readUnsignedInt();
const flag = xdr.readUnsignedInt();
const accessMask = xdr.readUnsignedInt();
const who = xdr.readString();
return new structs.Nfsv4Ace(type, flag, accessMask, who);
}
readSecInfoFlavor() {
const xdr = this.xdr;
const flavor = xdr.readUnsignedInt();
if (flavor === 6) {
const oid = xdr.readVarlenOpaque();
const qop = xdr.readUnsignedInt();
const service = xdr.readUnsignedInt();
const flavorInfo = new structs.Nfsv4RpcSecGssInfo(oid, qop, service);
return new structs.Nfsv4SecInfoFlavor(flavor, flavorInfo);
}
return new structs.Nfsv4SecInfoFlavor(flavor);
}
decodeAccessResponse() {
const xdr = this.xdr;
const status = xdr.readUnsignedInt();
if (status === 0) {
const supported = xdr.readUnsignedInt();
const access = xdr.readUnsignedInt();
return new msg.Nfsv4AccessResponse(status, new msg.Nfsv4AccessResOk(supported, access));
}
return new msg.Nfsv4AccessResponse(status);
}
decodeCloseRequest() {
const xdr = this.xdr;
const seqid = xdr.readUnsignedInt();
const openStateid = this.readStateid();
return new msg.Nfsv4CloseRequest(seqid, openStateid);
}
decodeCloseResponse() {
const status = this.xdr.readUnsignedInt();
if (status === 0) {
const openStateid = this.readStateid();
return new msg.Nfsv4CloseResponse(status, new msg.Nfsv4CloseResOk(openStateid));
}
return new msg.Nfsv4CloseResponse(status);
}
decodeCommitResponse() {
const status = this.xdr.readUnsignedInt();
if (status === 0) {
const writeverf = this.readVerifier();
return new msg.Nfsv4CommitResponse(status, new msg.Nfsv4CommitResOk(writeverf));
}
return new msg.Nfsv4CommitResponse(status);
}
decodeCreateRequest() {
const xdr = this.xdr;
const type = xdr.readUnsignedInt();
let objtype;
switch (type) {
case 5: {
const linkdata = xdr.readString();
objtype = new structs.Nfsv4CreateType(type, new structs.Nfsv4CreateTypeLink(linkdata));
break;
}
case 3:
case 4: {
const specdata1 = xdr.readUnsignedInt();
const specdata2 = xdr.readUnsignedInt();
const devdata = new structs.Nfsv4SpecData(specdata1, specdata2);
objtype = new structs.Nfsv4CreateType(type, new structs.Nfsv4CreateTypeDevice(devdata));
break;
}
default: {
objtype = new structs.Nfsv4CreateType(type, new structs.Nfsv4CreateTypeVoid());
break;
}
}
const objname = xdr.readString();
const createattrs = this.readFattr();
return new msg.Nfsv4CreateRequest(objtype, objname, createattrs);
}
decodeCreateResponse() {
const status = this.xdr.readUnsignedInt();
if (status === 0) {
const cinfo = this.readChangeInfo();
const attrset = this.readBitmap();
return new msg.Nfsv4CreateResponse(status, new msg.Nfsv4CreateResOk(cinfo, attrset));
}
return new msg.Nfsv4CreateResponse(status);
}
decodeDelegpurgeResponse() {
const status = this.xdr.readUnsignedInt();
return new msg.Nfsv4DelegpurgeResponse(status);
}
decodeDelegreturnResponse() {
const status = this.xdr.readUnsignedInt();
return new msg.Nfsv4DelegreturnResponse(status);
}
decodeGetattrRequest() {
const attrRequest = this.readBitmap();
return new msg.Nfsv4GetattrRequest(attrRequest);
}
decodeGetattrResponse() {
const status = this.xdr.readUnsignedInt();
if (status === 0) {
const objAttributes = this.readFattr();
return new msg.Nfsv4GetattrResponse(status, new msg.Nfsv4GetattrResOk(objAttributes));
}
return new msg.Nfsv4GetattrResponse(status);
}
decodeGetfhRequest() {
return new msg.Nfsv4GetfhRequest();
}
decodeGetfhResponse() {
const status = this.xdr.readUnsignedInt();
if (status === 0) {
const object = this.readFh();
return new msg.Nfsv4GetfhResponse(status, new msg.Nfsv4GetfhResOk(object));
}
return new msg.Nfsv4GetfhResponse(status);
}
decodeLinkRequest() {
const newname = this.xdr.readString();
return new msg.Nfsv4LinkRequest(newname);
}
decodeLinkResponse() {
const status = this.xdr.readUnsignedInt();
if (status === 0) {
const cinfo = this.readChangeInfo();
return new msg.Nfsv4LinkResponse(status, new msg.Nfsv4LinkResOk(cinfo));
}
return new msg.Nfsv4LinkResponse(status);
}
decodeLockRequest() {
const xdr = this.xdr;
const locktype = xdr.readUnsignedInt();
const reclaim = xdr.readBoolean();
const offset = xdr.readUnsignedHyper();
const length = xdr.readUnsignedHyper();
const locker = this.readLockOwnerInfo();
return new msg.Nfsv4LockRequest(locktype, reclaim, offset, length, locker);
}
decodeLockResponse() {
const xdr = this.xdr;
const status = xdr.readUnsignedInt();
if (status === 0) {
const lockStateid = this.readStateid();
return new msg.Nfsv4LockResponse(status, new msg.Nfsv4LockResOk(lockStateid));
}
else if (status === 10010) {
const offset = xdr.readUnsignedHyper();
const length = xdr.readUnsignedHyper();
const locktype = xdr.readUnsignedInt();
const owner = this.readLockOwner();
return new msg.Nfsv4LockResponse(status, undefined, new msg.Nfsv4LockResDenied(offset, length, locktype, owner));
}
return new msg.Nfsv4LockResponse(status);
}
decodeLocktRequest() {
const xdr = this.xdr;
const locktype = xdr.readUnsignedInt();
const offset = xdr.readUnsignedHyper();
const length = xdr.readUnsignedHyper();
const owner = this.readLockOwner();
return new msg.Nfsv4LocktRequest(locktype, offset, length, owner);
}
decodeLocktResponse() {
const xdr = this.xdr;
const status = xdr.readUnsignedInt();
if (status === 10010) {
const offset = xdr.readUnsignedHyper();
const length = xdr.readUnsignedHyper();
const locktype = xdr.readUnsignedInt();
const owner = this.readLockOwner();
return new msg.Nfsv4LocktResponse(status, new msg.Nfsv4LocktResDenied(offset, length, locktype, owner));
}
return new msg.Nfsv4LocktResponse(status);
}
decodeLockuRequest() {
const xdr = this.xdr;
const locktype = xdr.readUnsignedInt();
const seqid = xdr.readUnsignedInt();
const lockStateid = this.readStateid();
const offset = xdr.readUnsignedHyper();
const length = xdr.readUnsignedHyper();
return new msg.Nfsv4LockuRequest(locktype, seqid, lockStateid, offset, length);
}
decodeLockuResponse() {
const status = this.xdr.readUnsignedInt();
if (status === 0) {
const lockStateid = this.readStateid();
return new msg.Nfsv4LockuResponse(status, new msg.Nfsv4LockuResOk(lockStateid));
}
return new msg.Nfsv4LockuResponse(status);
}
decodeLookupRequest() {
const objname = this.xdr.readString();
return new msg.Nfsv4LookupRequest(objname);
}
decodeLookupResponse() {
const status = this.xdr.readUnsignedInt();
return new msg.Nfsv4LookupResponse(status);
}
decodeLookuppRequest() {
return new msg.Nfsv4LookuppRequest();
}
decodeLookuppResponse() {
const status = this.xdr.readUnsignedInt();
return new msg.Nfsv4LookuppResponse(status);
}
decodeNverifyRequest() {
const objAttributes = this.readFattr();
return new msg.Nfsv4NverifyRequest(objAttributes);
}
decodeNverifyResponse() {
const status = this.xdr.readUnsignedInt();
return new msg.Nfsv4NverifyResponse(status);
}
decodeOpenRequest() {
const xdr = this.xdr;
const seqid = xdr.readUnsignedInt();
const shareAccess = xdr.readUnsignedInt();
const shareDeny = xdr.readUnsignedInt();
const owner = this.readOpenOwner();
const openhow = this.readOpenHow();
const claim = this.readOpenClaim();
return new msg.Nfsv4OpenRequest(seqid, shareAccess, shareDeny, owner, openhow, claim);
}
decodeOpenResponse() {
const xdr = this.xdr;
const status = xdr.readUnsignedInt();
if (status === 0) {
const stateid = this.readStateid();
const cinfo = this.readChangeInfo();
const rflags = xdr.readUnsignedInt();
const attrset = this.readBitmap();
const delegation = this.readOpenDelegation();
return new msg.Nfsv4OpenResponse(status, new msg.Nfsv4OpenResOk(stateid, cinfo, rflags, attrset, delegation));
}
return new msg.Nfsv4OpenResponse(status);
}
decodeOpenattrRequest() {
const createdir = this.xdr.readBoolean();
return new msg.Nfsv4OpenattrRequest(createdir);
}
decodeOpenattrResponse() {
const status = this.xdr.readUnsignedInt();
return new msg.Nfsv4OpenattrResponse(status);
}
decodeOpenConfirmRequest() {
const openStateid = this.readStateid();
const seqid = this.xdr.readUnsignedInt();
return new msg.Nfsv4OpenConfirmRequest(openStateid, seqid);
}
decodeOpenConfirmResponse() {
const status = this.xdr.readUnsignedInt();
if (status === 0) {
const openStateid = this.readStateid();
return new msg.Nfsv4OpenConfirmResponse(status, new msg.Nfsv4OpenConfirmResOk(openStateid));
}
return new msg.Nfsv4OpenConfirmResponse(status);
}
decodeOpenDowngradeRequest() {
const xdr = this.xdr;
const openStateid = this.readStateid();
const seqid = xdr.readUnsignedInt();
const shareAccess = xdr.readUnsignedInt();
const shareDeny = xdr.readUnsignedInt();
return new msg.Nfsv4OpenDowngradeRequest(openStateid, seqid, shareAccess, shareDeny);
}
decodeOpenDowngradeResponse() {
const status = this.xdr.readUnsignedInt();
if (status === 0) {
const openStateid = this.readStateid();
return new msg.Nfsv4OpenDowngradeResponse(status, new msg.Nfsv4OpenDowngradeResOk(openStateid));
}
return new msg.Nfsv4OpenDowngradeResponse(status);
}
decodePutfhRequest() {
const object = this.readFh();
return new msg.Nfsv4PutfhRequest(object);
}
decodePutfhResponse() {
const status = this.xdr.readUnsignedInt();
return new msg.Nfsv4PutfhResponse(status);
}
decodePutrootfhResponse() {
const status = this.xdr.readUnsignedInt();
return new msg.Nfsv4PutrootfhResponse(status);
}
decodeReadRequest() {
const xdr = this.xdr;
const stateid = this.readStateid();
const offset = xdr.readUnsignedHyper();
const count = xdr.readUnsignedInt();
return new msg.Nfsv4ReadRequest(stateid, offset, count);
}
decodeReadResponse() {
const xdr = this.xdr;
const status = xdr.readUnsignedInt();
if (status === 0) {
const eof = xdr.readBoolean();
const data = xdr.readVarlenOpaque();
return new msg.Nfsv4ReadResponse(status, new msg.Nfsv4ReadResOk(eof, data));
}
return new msg.Nfsv4ReadResponse(status);
}
decodeReaddirRequest() {
const xdr = this.xdr;
const cookie = xdr.readUnsignedHyper();
const cookieverf = this.readVerifier();
const dircount = xdr.readUnsignedInt();
const maxcount = xdr.readUnsignedInt();
const attrRequest = this.readBitmap();
return new msg.Nfsv4ReaddirRequest(cookie, cookieverf, dircount, maxcount, attrRequest);
}
decodeReaddirResponse() {
const xdr = this.xdr;
const status = xdr.readUnsignedInt();
if (status === 0) {
const cookieverf = this.readVerifier();
const entries = [];
while (xdr.readBoolean()) {
const cookie = xdr.readUnsignedHyper();
const name = xdr.readString();
const attrs = this.readFattr();
entries.push(new structs.Nfsv4Entry(cookie, name, attrs));
}
const eof = xdr.readBoolean();
return new msg.Nfsv4ReaddirResponse(status, new msg.Nfsv4ReaddirResOk(cookieverf, entries, eof));
}
return new msg.Nfsv4ReaddirResponse(status);
}
decodeReadlinkRequest() {
return new msg.Nfsv4ReadlinkRequest();
}
decodeReadlinkResponse() {
const xdr = this.xdr;
const status = xdr.readUnsignedInt();
if (status === 0) {
const link = xdr.readString();
return new msg.Nfsv4ReadlinkResponse(status, new msg.Nfsv4ReadlinkResOk(link));
}
return new msg.Nfsv4ReadlinkResponse(status);
}
decodeRemoveRequest() {
const target = this.xdr.readString();
return new msg.Nfsv4RemoveRequest(target);
}
decodeRemoveResponse() {
const status = this.xdr.readUnsignedInt();
if (status === 0) {
const cinfo = this.readChangeInfo();
return new msg.Nfsv4RemoveResponse(status, new msg.Nfsv4RemoveResOk(cinfo));
}
return new msg.Nfsv4RemoveResponse(status);
}
decodeRenameRequest() {
const xdr = this.xdr;
const oldname = xdr.readString();
const newname = xdr.readString();
return new msg.Nfsv4RenameRequest(oldname, newname);
}
decodeRenameResponse() {
const xdr = this.xdr;
const status = xdr.readUnsignedInt();
if (status === 0) {
const sourceCinfo = this.readChangeInfo();
const targetCinfo = this.readChangeInfo();
return new msg.Nfsv4RenameResponse(status, new msg.Nfsv4RenameResOk(sourceCinfo, targetCinfo));
}
return new msg.Nfsv4RenameResponse(status);
}
decodeRenewRequest() {
const clientid = this.xdr.readUnsignedHyper();
return new msg.Nfsv4RenewRequest(clientid);
}
decodeRenewResponse() {
const status = this.xdr.readUnsignedInt();
return new msg.Nfsv4RenewResponse(status);
}
decodeRestorefhRequest() {
return new msg.Nfsv4RestorefhRequest();
}
decodeRestorefhResponse() {
const status = this.xdr.readUnsignedInt();
return new msg.Nfsv4RestorefhResponse(status);
}
decodeSavefhRequest() {
return new msg.Nfsv4SavefhRequest();
}
decodeSavefhResponse() {
const status = this.xdr.readUnsignedInt();
return new msg.Nfsv4SavefhResponse(status);
}
decodeSecinfoRequest() {
const name = this.xdr.readString();
return new msg.Nfsv4SecinfoRequest(name);
}
decodeSecinfoResponse() {
const xdr = this.xdr;
const status = xdr.readUnsignedInt();
if (status === 0) {
const count = xdr.readUnsignedInt();
const flavors = [];
for (let i = 0; i < count; i++)
flavors.push(this.readSecInfoFlavor());
return new msg.Nfsv4SecinfoResponse(status, new msg.Nfsv4SecinfoResOk(flavors));
}
return new msg.Nfsv4SecinfoResponse(status);
}
decodeSetattrRequest() {
const stateid = this.readStateid();
const objAttributes = this.readFattr();
return new msg.Nfsv4SetattrRequest(stateid, objAttributes);
}
decodeSetattrResponse() {
const status = this.xdr.readUnsignedInt();
const attrset = this.readBitmap();
return new msg.Nfsv4SetattrResponse(status, new msg.Nfsv4SetattrResOk(attrset));
}
decodeSetclientidRequest() {
const client = this.readClientId();
const callback = this.readCbClient();
const callbackIdent = this.xdr.readUnsignedInt();
return new msg.Nfsv4SetclientidRequest(client, callback, callbackIdent);
}
decodeSetclientidResponse() {
const xdr = this.xdr;
const status = xdr.readUnsignedInt();
if (status === 0) {
const clientid = xdr.readUnsignedHyper();
const setclientidConfirm = this.readVerifier();
return new msg.Nfsv4SetclientidResponse(status, new msg.Nfsv4SetclientidResOk(clientid, setclientidConfirm));
}
return new msg.Nfsv4SetclientidResponse(status);
}
decodeSetclientidConfirmRequest() {
const clientid = this.xdr.readUnsignedHyper();
const setclientidConfirm = this.readVerifier();
return new msg.Nfsv4SetclientidConfirmRequest(clientid, setclientidConfirm);
}
decodeSetclientidConfirmResponse() {
const status = this.xdr.readUnsignedInt();
return new msg.Nfsv4SetclientidConfirmResponse(status);
}
decodeVerifyRequest() {
const objAttributes = this.readFattr();
return new msg.Nfsv4VerifyRequest(objAttributes);
}
decodeVerifyResponse() {
const status = this.xdr.readUnsignedInt();
return new msg.Nfsv4VerifyResponse(status);
}
decodeWriteRequest() {
const xdr = this.xdr;
const stateid = this.readStateid();
const offset = xdr.readUnsignedHyper();
const stable = xdr.readUnsignedInt();
const data = xdr.readVarlenOpaque();
return new msg.Nfsv4WriteRequest(stateid, offset, stable, data);
}
decodeWriteResponse() {
const xdr = this.xdr;
const status = xdr.readUnsignedInt();
if (status === 0) {
const count = xdr.readUnsignedInt();
const committed = xdr.readUnsignedInt();
const writeverf = this.readVerifier();
return new msg.Nfsv4WriteResponse(status, new msg.Nfsv4WriteResOk(count, committed, writeverf));
}
return new msg.Nfsv4WriteResponse(status);
}
decodeReleaseLockOwnerRequest() {
const lockOwner = this.readLockOwner();
return new msg.Nfsv4ReleaseLockOwnerRequest(lockOwner);
}
decodeReleaseLockOwnerResponse() {
const status = this.xdr.readUnsignedInt();
return new msg.Nfsv4ReleaseLockOwnerResponse(status);
}
decodeIllegalRequest() {
return new msg.Nfsv4IllegalRequest();
}
decodeIllegalResponse() {
const status = this.xdr.readUnsignedInt();
return new msg.Nfsv4IllegalResponse(status);
}
decodeCbCompound(reader, isRequest) {
this.xdr.reader = reader;
const startPos = reader.x;
try {
if (isRequest) {
return this.decodeCbCompoundRequest();
}
else {
return this.decodeCbCompoundResponse();
}
}
catch (err) {
if (err instanceof RangeError) {
reader.x = startPos;
return undefined;
}
throw err;
}
}
decodeCbCompoundRequest() {
const xdr = this.xdr;
const tag = xdr.readString();
const minorversion = xdr.readUnsignedInt();
const callbackIdent = xdr.readUnsignedInt();
const argarray = [];
const count = xdr.readUnsignedInt();
for (let i = 0; i < count; i++) {
const op = xdr.readUnsignedInt();
const request = this.decodeCbRequest(op);
if (request)
argarray.push(request);
}
return new msg.Nfsv4CbCompoundRequest(tag, minorversion, callbackIdent, argarray);
}
decodeCbCompoundResponse() {
const xdr = this.xdr;
const status = xdr.readUnsignedInt();
const tag = xdr.readString();
const resarray = [];
const count = xdr.readUnsignedInt();
for (let i = 0; i < count; i++) {
const op = xdr.readUnsignedInt();
const response = this.decodeCbResponse(op);
if (response)
resarray.push(response);
}
return new msg.Nfsv4CbCompoundResponse(status, tag, resarray);
}
decodeCbRequest(op) {
switch (op) {
case 3:
return this.decodeCbGetattrRequest();
case 4:
return this.decodeCbRecallRequest();
case 10044:
return this.decodeCbIllegalRequest();
default:
throw new errors_1.Nfsv4DecodingError(`Unknown callback operation: ${op}`);
}
}
decodeCbResponse(op) {
switch (op) {
case 3:
return this.decodeCbGetattrResponse();
case 4:
return this.decodeCbRecallResponse();
case 10044:
return this.decodeCbIllegalResponse();
default:
throw new errors_1.Nfsv4DecodingError(`Unknown callback operation: ${op}`);
}
}
decodeCbGetattrRequest() {
const fh = this.readFh();
const attrRequest = this.readBitmap();
return new msg.Nfsv4CbGetattrRequest(fh, attrRequest);
}
decodeCbGetattrResponse() {
const status = this.xdr.readUnsignedInt();
if (status === 0) {
const objAttributes = this.readFattr();
return new msg.Nfsv4CbGetattrResponse(status, new msg.Nfsv4CbGetattrResOk(objAttributes));
}
return new msg.Nfsv4CbGetattrResponse(status);
}
decodeCbRecallRequest() {
const stateid = this.readStateid();
const truncate = this.xdr.readBoolean();
const fh = this.readFh();
return new msg.Nfsv4CbRecallRequest(stateid, truncate, fh);
}
decodeCbRecallResponse() {
const status = this.xdr.readUnsignedInt();
return new msg.Nfsv4CbRecallResponse(status);
}
decodeCbIllegalRequest() {
return new msg.Nfsv4CbIllegalRequest();
}
decodeCbIllegalResponse() {
const status = this.xdr.readUnsignedInt();
return new msg.Nfsv4CbIllegalResponse(status);
}
}
exports.Nfsv4Decoder = Nfsv4Decoder;
//# sourceMappingURL=Nfsv4Decoder.js.map
File diff suppressed because one or more lines are too long
+12
View File
@@ -0,0 +1,12 @@
import { XdrEncoder } from '../../xdr/XdrEncoder';
import * as msg from './messages';
import type { IWriter, IWriterGrowable } from '@jsonjoy.com/util/lib/buffers';
export declare class Nfsv4Encoder<W extends IWriter & IWriterGrowable = IWriter & IWriterGrowable> {
readonly writer: W;
readonly xdr: XdrEncoder;
constructor(writer?: W);
encodeCompound(compound: msg.Nfsv4CompoundRequest | msg.Nfsv4CompoundResponse, isRequest?: boolean): Uint8Array;
writeCompound(compound: msg.Nfsv4CompoundRequest | msg.Nfsv4CompoundResponse, isRequest: boolean): void;
encodeCbCompound(compound: msg.Nfsv4CbCompoundRequest | msg.Nfsv4CbCompoundResponse, isRequest?: boolean): Uint8Array;
writeCbCompound(compound: msg.Nfsv4CbCompoundRequest | msg.Nfsv4CbCompoundResponse, isRequest: boolean): void;
}
+27
View File
@@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Nfsv4Encoder = void 0;
const Writer_1 = require("@jsonjoy.com/util/lib/buffers/Writer");
const XdrEncoder_1 = require("../../xdr/XdrEncoder");
class Nfsv4Encoder {
constructor(writer = new Writer_1.Writer()) {
this.writer = writer;
this.xdr = new XdrEncoder_1.XdrEncoder(writer);
}
encodeCompound(compound, isRequest) {
compound.encode(this.xdr);
return this.writer.flush();
}
writeCompound(compound, isRequest) {
compound.encode(this.xdr);
}
encodeCbCompound(compound, isRequest) {
compound.encode(this.xdr);
return this.writer.flush();
}
writeCbCompound(compound, isRequest) {
compound.encode(this.xdr);
}
}
exports.Nfsv4Encoder = Nfsv4Encoder;
//# sourceMappingURL=Nfsv4Encoder.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"Nfsv4Encoder.js","sourceRoot":"","sources":["../../../src/nfs/v4/Nfsv4Encoder.ts"],"names":[],"mappings":";;;AAAA,iEAA4D;AAC5D,qDAAgD;AAIhD,MAAa,YAAY;IAGvB,YAA4B,SAAY,IAAI,eAAM,EAAS;QAA/B,WAAM,GAAN,MAAM,CAAyB;QACzD,IAAI,CAAC,GAAG,GAAG,IAAI,uBAAU,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IAEM,cAAc,CACnB,QAA8D,EAC9D,SAAmB;QAEnB,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;IAEM,aAAa,CAAC,QAA8D,EAAE,SAAkB;QACrG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAEM,gBAAgB,CACrB,QAAkE,EAClE,SAAmB;QAEnB,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;IAEM,eAAe,CAAC,QAAkE,EAAE,SAAkB;QAC3G,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;CACF;AA9BD,oCA8BC"}
+32
View File
@@ -0,0 +1,32 @@
import { Nfsv4Encoder } from './Nfsv4Encoder';
import { RpcMessageEncoder } from '../../rpc/RpcMessageEncoder';
import { RmRecordEncoder } from '../../rm/RmRecordEncoder';
import { Nfsv4Proc, Nfsv4CbProc } from './constants';
import { RpcOpaqueAuth } from '../../rpc/messages';
import { XdrEncoder } from '../../xdr';
import type * as msg from './messages';
import type { IWriter, IWriterGrowable } from '@jsonjoy.com/util/lib/buffers';
export declare class Nfsv4FullEncoder<W extends IWriter & IWriterGrowable = IWriter & IWriterGrowable> {
readonly writer: W;
readonly nfsEncoder: Nfsv4Encoder<W>;
readonly rpcEncoder: RpcMessageEncoder<W>;
readonly rmEncoder: RmRecordEncoder<W>;
readonly xdr: XdrEncoder;
constructor(writer?: W);
encodeCall(xid: number, proc: Nfsv4Proc, cred: RpcOpaqueAuth, verf: RpcOpaqueAuth, request: msg.Nfsv4CompoundRequest): Uint8Array;
writeCall(xid: number, proc: Nfsv4Proc, cred: RpcOpaqueAuth, verf: RpcOpaqueAuth, request: msg.Nfsv4CompoundRequest): void;
encodeAcceptedCompoundReply(xid: number, proc: Nfsv4Proc, verf: RpcOpaqueAuth, response: msg.Nfsv4CompoundResponse): Uint8Array;
writeAcceptedCompoundReply(xid: number, verf: RpcOpaqueAuth, compound: msg.Nfsv4CompoundResponse): void;
encodeRejectedReply(xid: number, rejectStat: number, mismatchInfo?: {
low: number;
high: number;
}, authStat?: number): Uint8Array;
writeRejectedReply(xid: number, rejectStat: number, mismatchInfo?: {
low: number;
high: number;
}, authStat?: number): void;
encodeCbCall(xid: number, cbProgram: number, proc: Nfsv4CbProc, cred: RpcOpaqueAuth, verf: RpcOpaqueAuth, request: msg.Nfsv4CbCompoundRequest): Uint8Array;
writeCbCall(xid: number, cbProgram: number, proc: Nfsv4CbProc, cred: RpcOpaqueAuth, verf: RpcOpaqueAuth, request: msg.Nfsv4CbCompoundRequest): void;
encodeCbAcceptedReply(xid: number, proc: Nfsv4CbProc, verf: RpcOpaqueAuth, response: msg.Nfsv4CbCompoundResponse): Uint8Array;
writeCbAcceptedReply(xid: number, proc: Nfsv4CbProc, verf: RpcOpaqueAuth, response: msg.Nfsv4CbCompoundResponse): void;
}
+72
View File
@@ -0,0 +1,72 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Nfsv4FullEncoder = void 0;
const Writer_1 = require("@jsonjoy.com/buffers/lib/Writer");
const Nfsv4Encoder_1 = require("./Nfsv4Encoder");
const RpcMessageEncoder_1 = require("../../rpc/RpcMessageEncoder");
const RmRecordEncoder_1 = require("../../rm/RmRecordEncoder");
class Nfsv4FullEncoder {
constructor(writer = new Writer_1.Writer()) {
this.writer = writer;
this.nfsEncoder = new Nfsv4Encoder_1.Nfsv4Encoder(writer);
this.rpcEncoder = new RpcMessageEncoder_1.RpcMessageEncoder(writer);
this.rmEncoder = new RmRecordEncoder_1.RmRecordEncoder(writer);
this.xdr = this.nfsEncoder.xdr;
}
encodeCall(xid, proc, cred, verf, request) {
this.writeCall(xid, proc, cred, verf, request);
return this.writer.flush();
}
writeCall(xid, proc, cred, verf, request) {
const rm = this.rmEncoder;
const state = rm.startRecord();
this.rpcEncoder.writeCall(xid, 100003, 4, proc, cred, verf);
this.nfsEncoder.writeCompound(request, true);
rm.endRecord(state);
}
encodeAcceptedCompoundReply(xid, proc, verf, response) {
this.writeAcceptedCompoundReply(xid, verf, response);
return this.writer.flush();
}
writeAcceptedCompoundReply(xid, verf, compound) {
const rm = this.rmEncoder;
const state = rm.startRecord();
this.rpcEncoder.writeAcceptedReply(xid, verf, 0);
compound.encode(this.xdr);
rm.endRecord(state);
}
encodeRejectedReply(xid, rejectStat, mismatchInfo, authStat) {
this.writeRejectedReply(xid, rejectStat, mismatchInfo, authStat);
return this.writer.flush();
}
writeRejectedReply(xid, rejectStat, mismatchInfo, authStat) {
const rm = this.rmEncoder;
const state = rm.startRecord();
this.rpcEncoder.writeRejectedReply(xid, rejectStat, mismatchInfo, authStat);
rm.endRecord(state);
}
encodeCbCall(xid, cbProgram, proc, cred, verf, request) {
this.writeCbCall(xid, cbProgram, proc, cred, verf, request);
return this.writer.flush();
}
writeCbCall(xid, cbProgram, proc, cred, verf, request) {
const rm = this.rmEncoder;
const state = rm.startRecord();
this.rpcEncoder.writeCall(xid, cbProgram, 4, proc, cred, verf);
this.nfsEncoder.writeCbCompound(request, true);
rm.endRecord(state);
}
encodeCbAcceptedReply(xid, proc, verf, response) {
this.writeCbAcceptedReply(xid, proc, verf, response);
return this.writer.flush();
}
writeCbAcceptedReply(xid, proc, verf, response) {
const rm = this.rmEncoder;
const state = rm.startRecord();
this.rpcEncoder.writeAcceptedReply(xid, verf, 0);
this.nfsEncoder.writeCbCompound(response, false);
rm.endRecord(state);
}
}
exports.Nfsv4FullEncoder = Nfsv4FullEncoder;
//# sourceMappingURL=Nfsv4FullEncoder.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Nfsv4FullEncoder.js","sourceRoot":"","sources":["../../../src/nfs/v4/Nfsv4FullEncoder.ts"],"names":[],"mappings":"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"}
+17
View File
@@ -0,0 +1,17 @@
import { Nfsv4Attr } from './constants';
export declare const PER_SERVER_ATTRS: Set<Nfsv4Attr>;
export declare const PER_FS_ATTRS: Set<Nfsv4Attr>;
export declare const HOMOGENEOUS_ATTRS: Set<Nfsv4Attr>;
export declare const GET_ONLY_ATTRS: Set<Nfsv4Attr>;
export declare const SET_ONLY_ATTRS: Set<Nfsv4Attr>;
export declare const REQUIRED_ATTRS: Set<Nfsv4Attr>;
export declare const RECOMMENDED_ATTRS: Set<Nfsv4Attr>;
export declare const STAT_ATTRS: Set<Nfsv4Attr>;
export declare const FS_ATTRS: Set<Nfsv4Attr>;
export declare const parseBitmask: (mask: number[]) => Set<number>;
export declare const overlaps: <T>(a: Set<T>, b: Set<T>) => boolean;
export declare const containsSetOnlyAttr: (requestedAttrs: Set<number>) => boolean;
export declare const requiresLstat: (requestedAttrs: Set<number>) => boolean;
export declare const requiresFsStats: (requestedAttrs: Set<number>) => boolean;
export declare const setBit: (mask: number[], attrNum: Nfsv4Attr) => void;
export declare const attrNumsToBitmap: (attrNums: Nfsv4Attr[]) => number[];
+203
View File
@@ -0,0 +1,203 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.attrNumsToBitmap = exports.setBit = exports.requiresFsStats = exports.requiresLstat = exports.containsSetOnlyAttr = exports.overlaps = exports.parseBitmask = exports.FS_ATTRS = exports.STAT_ATTRS = exports.RECOMMENDED_ATTRS = exports.REQUIRED_ATTRS = exports.SET_ONLY_ATTRS = exports.GET_ONLY_ATTRS = exports.HOMOGENEOUS_ATTRS = exports.PER_FS_ATTRS = exports.PER_SERVER_ATTRS = void 0;
exports.PER_SERVER_ATTRS = new Set([10]);
exports.PER_FS_ATTRS = new Set([
0,
2,
5,
6,
9,
13,
15,
16,
17,
18,
21,
22,
23,
24,
26,
27,
29,
30,
31,
34,
42,
43,
44,
51,
]);
exports.HOMOGENEOUS_ATTRS = new Set([
0,
8,
26,
5,
6,
]);
exports.GET_ONLY_ATTRS = new Set([
0,
1,
2,
3,
5,
6,
7,
8,
9,
10,
11,
19,
13,
15,
16,
17,
18,
20,
21,
22,
23,
24,
26,
27,
28,
29,
30,
31,
55,
34,
35,
38,
39,
40,
41,
42,
43,
44,
45,
47,
51,
52,
53,
]);
exports.SET_ONLY_ATTRS = new Set([48, 54]);
exports.REQUIRED_ATTRS = new Set([
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
19,
]);
exports.RECOMMENDED_ATTRS = new Set([
12,
13,
14,
15,
16,
17,
18,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
55,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
]);
exports.STAT_ATTRS = new Set([
1,
3,
4,
20,
33,
35,
41,
45,
47,
52,
53,
]);
exports.FS_ATTRS = new Set([
21,
22,
23,
42,
43,
44,
]);
const parseBitmask = (mask) => {
const attrs = new Set();
const length = mask.length;
for (let i = 0, word = mask[0], base = 0; i < length; i++, word = mask[i], base = i * 32)
for (let bit = 0; word; bit++, word >>>= 1)
if (word & 1)
attrs.add(base + bit);
return attrs;
};
exports.parseBitmask = parseBitmask;
const overlaps = (a, b) => {
for (const element of b)
if (a.has(element))
return true;
return false;
};
exports.overlaps = overlaps;
const containsSetOnlyAttr = (requestedAttrs) => (0, exports.overlaps)(requestedAttrs, exports.SET_ONLY_ATTRS);
exports.containsSetOnlyAttr = containsSetOnlyAttr;
const requiresLstat = (requestedAttrs) => (0, exports.overlaps)(requestedAttrs, exports.STAT_ATTRS);
exports.requiresLstat = requiresLstat;
const requiresFsStats = (requestedAttrs) => (0, exports.overlaps)(requestedAttrs, exports.FS_ATTRS);
exports.requiresFsStats = requiresFsStats;
const setBit = (mask, attrNum) => {
const wordIndex = Math.floor(attrNum / 32);
const bitIndex = attrNum % 32;
while (mask.length <= wordIndex)
mask.push(0);
mask[wordIndex] |= 1 << bitIndex;
};
exports.setBit = setBit;
const attrNumsToBitmap = (attrNums) => {
const mask = [];
for (const attrNum of attrNums)
(0, exports.setBit)(mask, attrNum);
return mask;
};
exports.attrNumsToBitmap = attrNumsToBitmap;
//# sourceMappingURL=attributes.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"attributes.js","sourceRoot":"","sources":["../../../src/nfs/v4/attributes.ts"],"names":[],"mappings":"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"}
+60
View File
@@ -0,0 +1,60 @@
import * as msg from './messages';
import * as structs from './structs';
import { Nfsv4LockType } from './constants';
export declare const nfs: {
PUTROOTFH(): msg.Nfsv4PutrootfhRequest;
PUTFH(fh: structs.Nfsv4Fh): msg.Nfsv4PutfhRequest;
PUTPUBFH(): msg.Nfsv4PutpubfhRequest;
GETFH(): msg.Nfsv4GetfhRequest;
LOOKUP(name: string): msg.Nfsv4LookupRequest;
LOOKUPP(): msg.Nfsv4LookuppRequest;
GETATTR(attrBitmap: number[]): msg.Nfsv4GetattrRequest;
READDIR(attrBitmap: number | number[], cookieverf?: Uint8Array, cookie?: bigint, dircount?: number, maxcount?: number): msg.Nfsv4ReaddirRequest;
ACCESS(accessMask?: number): msg.Nfsv4AccessRequest;
READ(offset: bigint, count: number, stateid?: structs.Nfsv4Stateid): msg.Nfsv4ReadRequest;
WRITE(stateid: structs.Nfsv4Stateid, offset: bigint, stable: number, data: Uint8Array): msg.Nfsv4WriteRequest;
COMMIT(offset: bigint, count: number): msg.Nfsv4CommitRequest;
CREATE(objtype: structs.Nfsv4CreateType, objname: string, createattrs: structs.Nfsv4Fattr): msg.Nfsv4CreateRequest;
LINK(newname: string): msg.Nfsv4LinkRequest;
READLINK(): msg.Nfsv4ReadlinkRequest;
SAVEFH(): msg.Nfsv4SavefhRequest;
RESTOREFH(): msg.Nfsv4RestorefhRequest;
SETATTR(stateid: structs.Nfsv4Stateid, attrs: structs.Nfsv4Fattr): msg.Nfsv4SetattrRequest;
VERIFY(attrs: structs.Nfsv4Fattr): msg.Nfsv4VerifyRequest;
NVERIFY(attrs: structs.Nfsv4Fattr): msg.Nfsv4NverifyRequest;
REMOVE(name: string): msg.Nfsv4RemoveRequest;
RENAME(oldname: string, newname: string): msg.Nfsv4RenameRequest;
RENEW(clientid: bigint): msg.Nfsv4RenewRequest;
SETCLIENTID(client: structs.Nfsv4ClientId, callback: structs.Nfsv4CbClient, callbackIdent: number): msg.Nfsv4SetclientidRequest;
SETCLIENTID_CONFIRM(clientid: bigint, verifier: structs.Nfsv4Verifier): msg.Nfsv4SetclientidConfirmRequest;
OPEN(seqid: number, shareAccess: number, shareDeny: number, owner: structs.Nfsv4OpenOwner, openhow: structs.Nfsv4OpenHow, claim: structs.Nfsv4OpenClaim): msg.Nfsv4OpenRequest;
CLOSE(seqid: number, openStateid: structs.Nfsv4Stateid): msg.Nfsv4CloseRequest;
OPEN_CONFIRM(openStateid: structs.Nfsv4Stateid, seqid: number): msg.Nfsv4OpenConfirmRequest;
OPEN_DOWNGRADE(openStateid: structs.Nfsv4Stateid, seqid: number, shareAccess: number, shareDeny: number): msg.Nfsv4OpenDowngradeRequest;
OPENATTR(createdir?: boolean): msg.Nfsv4OpenattrRequest;
SECINFO(name: string): msg.Nfsv4SecinfoRequest;
DELEGPURGE(clientid: bigint): msg.Nfsv4DelegpurgeRequest;
DELEGRETURN(stateid: structs.Nfsv4Stateid): msg.Nfsv4DelegreturnRequest;
LOCK(locktype: Nfsv4LockType, reclaim: boolean, offset: bigint, length: bigint, locker: structs.Nfsv4LockOwnerInfo): msg.Nfsv4LockRequest;
LOCKT(locktype: number, offset: bigint, length: bigint, owner: structs.Nfsv4LockOwner): msg.Nfsv4LocktRequest;
LOCKU(locktype: number, seqid: number, lockStateid: structs.Nfsv4Stateid, offset: bigint, length: bigint): msg.Nfsv4LockuRequest;
RELEASE_LOCKOWNER(lockOwner: structs.Nfsv4LockOwner): msg.Nfsv4ReleaseLockOwnerRequest;
Verifier(data?: Uint8Array): structs.Nfsv4Verifier;
Stateid(seqid?: number, other?: Uint8Array): structs.Nfsv4Stateid;
Fattr(attrNums: number[], attrVals: Uint8Array): structs.Nfsv4Fattr;
ClientId(verifier: structs.Nfsv4Verifier, id: Uint8Array): structs.Nfsv4ClientId;
CbClient(cbProgram: number, rNetid: string, rAddr: string): structs.Nfsv4CbClient;
Bitmap(attrNums: number[]): structs.Nfsv4Bitmap;
CreateTypeFile(): structs.Nfsv4CreateType;
CreateTypeDir(): structs.Nfsv4CreateType;
OpenOwner(clientid: bigint, owner: Uint8Array): structs.Nfsv4OpenOwner;
OpenClaimNull(filename: string): structs.Nfsv4OpenClaim;
OpenHowNoCreate(): structs.Nfsv4OpenHow;
OpenHowCreateUnchecked(createattrs?: structs.Nfsv4Fattr): structs.Nfsv4OpenHow;
OpenHowCreateGuarded(createattrs?: structs.Nfsv4Fattr): structs.Nfsv4OpenHow;
OpenHowCreateExclusive(verifier: structs.Nfsv4Verifier): structs.Nfsv4OpenHow;
LockOwner(clientid: bigint, owner: Uint8Array): structs.Nfsv4LockOwner;
NewLockOwner(openSeqid: number, openStateid: structs.Nfsv4Stateid, lockSeqid: number, lockOwner: structs.Nfsv4LockOwner): structs.Nfsv4LockOwnerInfo;
ExistingLockOwner(lockStateid: structs.Nfsv4Stateid, lockSeqid: number): structs.Nfsv4LockOwnerInfo;
ILLEGAL(): msg.Nfsv4IllegalRequest;
};
+187
View File
@@ -0,0 +1,187 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.nfs = void 0;
const tslib_1 = require("tslib");
const attributes_1 = require("./attributes");
const msg = tslib_1.__importStar(require("./messages"));
const structs = tslib_1.__importStar(require("./structs"));
exports.nfs = {
PUTROOTFH() {
return new msg.Nfsv4PutrootfhRequest();
},
PUTFH(fh) {
return new msg.Nfsv4PutfhRequest(fh);
},
PUTPUBFH() {
return new msg.Nfsv4PutpubfhRequest();
},
GETFH() {
return new msg.Nfsv4GetfhRequest();
},
LOOKUP(name) {
return new msg.Nfsv4LookupRequest(name);
},
LOOKUPP() {
return new msg.Nfsv4LookuppRequest();
},
GETATTR(attrBitmap) {
return new msg.Nfsv4GetattrRequest(new structs.Nfsv4Bitmap(attrBitmap));
},
READDIR(attrBitmap, cookieverf, cookie, dircount, maxcount) {
const bitmap = Array.isArray(attrBitmap) ? attrBitmap : [attrBitmap];
const verifier = cookieverf || new Uint8Array(8);
return new msg.Nfsv4ReaddirRequest(cookie ?? BigInt(0), new structs.Nfsv4Verifier(verifier), dircount ?? 1000, maxcount ?? 8192, new structs.Nfsv4Bitmap(bitmap));
},
ACCESS(accessMask = 0x0000003f) {
return new msg.Nfsv4AccessRequest(accessMask);
},
READ(offset, count, stateid) {
const sid = stateid || new structs.Nfsv4Stateid(0, new Uint8Array(12));
return new msg.Nfsv4ReadRequest(sid, offset, count);
},
WRITE(stateid, offset, stable, data) {
return new msg.Nfsv4WriteRequest(stateid, offset, stable, data);
},
COMMIT(offset, count) {
return new msg.Nfsv4CommitRequest(offset, count);
},
CREATE(objtype, objname, createattrs) {
return new msg.Nfsv4CreateRequest(objtype, objname, createattrs);
},
LINK(newname) {
return new msg.Nfsv4LinkRequest(newname);
},
READLINK() {
return new msg.Nfsv4ReadlinkRequest();
},
SAVEFH() {
return new msg.Nfsv4SavefhRequest();
},
RESTOREFH() {
return new msg.Nfsv4RestorefhRequest();
},
SETATTR(stateid, attrs) {
return new msg.Nfsv4SetattrRequest(stateid, attrs);
},
VERIFY(attrs) {
return new msg.Nfsv4VerifyRequest(attrs);
},
NVERIFY(attrs) {
return new msg.Nfsv4NverifyRequest(attrs);
},
REMOVE(name) {
return new msg.Nfsv4RemoveRequest(name);
},
RENAME(oldname, newname) {
return new msg.Nfsv4RenameRequest(oldname, newname);
},
RENEW(clientid) {
return new msg.Nfsv4RenewRequest(clientid);
},
SETCLIENTID(client, callback, callbackIdent) {
return new msg.Nfsv4SetclientidRequest(client, callback, callbackIdent);
},
SETCLIENTID_CONFIRM(clientid, verifier) {
return new msg.Nfsv4SetclientidConfirmRequest(clientid, verifier);
},
OPEN(seqid, shareAccess, shareDeny, owner, openhow, claim) {
return new msg.Nfsv4OpenRequest(seqid, shareAccess, shareDeny, owner, openhow, claim);
},
CLOSE(seqid, openStateid) {
return new msg.Nfsv4CloseRequest(seqid, openStateid);
},
OPEN_CONFIRM(openStateid, seqid) {
return new msg.Nfsv4OpenConfirmRequest(openStateid, seqid);
},
OPEN_DOWNGRADE(openStateid, seqid, shareAccess, shareDeny) {
return new msg.Nfsv4OpenDowngradeRequest(openStateid, seqid, shareAccess, shareDeny);
},
OPENATTR(createdir = false) {
return new msg.Nfsv4OpenattrRequest(createdir);
},
SECINFO(name) {
return new msg.Nfsv4SecinfoRequest(name);
},
DELEGPURGE(clientid) {
return new msg.Nfsv4DelegpurgeRequest(clientid);
},
DELEGRETURN(stateid) {
return new msg.Nfsv4DelegreturnRequest(stateid);
},
LOCK(locktype, reclaim, offset, length, locker) {
return new msg.Nfsv4LockRequest(locktype, reclaim, offset, length, locker);
},
LOCKT(locktype, offset, length, owner) {
return new msg.Nfsv4LocktRequest(locktype, offset, length, owner);
},
LOCKU(locktype, seqid, lockStateid, offset, length) {
return new msg.Nfsv4LockuRequest(locktype, seqid, lockStateid, offset, length);
},
RELEASE_LOCKOWNER(lockOwner) {
return new msg.Nfsv4ReleaseLockOwnerRequest(lockOwner);
},
Verifier(data) {
return new structs.Nfsv4Verifier(data || new Uint8Array(8));
},
Stateid(seqid = 0, other) {
return new structs.Nfsv4Stateid(seqid, other || new Uint8Array(12));
},
Fattr(attrNums, attrVals) {
const bitmap = new structs.Nfsv4Bitmap((0, attributes_1.attrNumsToBitmap)(attrNums));
return new structs.Nfsv4Fattr(bitmap, attrVals);
},
ClientId(verifier, id) {
return new structs.Nfsv4ClientId(verifier, id);
},
CbClient(cbProgram, rNetid, rAddr) {
const cbLocation = new structs.Nfsv4ClientAddr(rNetid, rAddr);
return new structs.Nfsv4CbClient(cbProgram, cbLocation);
},
Bitmap(attrNums) {
return new structs.Nfsv4Bitmap((0, attributes_1.attrNumsToBitmap)(attrNums));
},
CreateTypeFile() {
return new structs.Nfsv4CreateType(1, new structs.Nfsv4CreateTypeVoid());
},
CreateTypeDir() {
return new structs.Nfsv4CreateType(2, new structs.Nfsv4CreateTypeVoid());
},
OpenOwner(clientid, owner) {
return new structs.Nfsv4OpenOwner(clientid, owner);
},
OpenClaimNull(filename) {
return new structs.Nfsv4OpenClaim(0, new structs.Nfsv4OpenClaimNull(filename));
},
OpenHowNoCreate() {
return new structs.Nfsv4OpenHow(0);
},
OpenHowCreateUnchecked(createattrs) {
const attrs = createattrs || new structs.Nfsv4Fattr(new structs.Nfsv4Bitmap([]), new Uint8Array(0));
const how = new structs.Nfsv4CreateHow(0, new structs.Nfsv4CreateAttrs(attrs));
return new structs.Nfsv4OpenHow(1, how);
},
OpenHowCreateGuarded(createattrs) {
const attrs = createattrs || new structs.Nfsv4Fattr(new structs.Nfsv4Bitmap([]), new Uint8Array(0));
const how = new structs.Nfsv4CreateHow(1, new structs.Nfsv4CreateAttrs(attrs));
return new structs.Nfsv4OpenHow(1, how);
},
OpenHowCreateExclusive(verifier) {
const how = new structs.Nfsv4CreateHow(2, new structs.Nfsv4CreateVerf(verifier));
return new structs.Nfsv4OpenHow(1, how);
},
LockOwner(clientid, owner) {
return new structs.Nfsv4LockOwner(clientid, owner);
},
NewLockOwner(openSeqid, openStateid, lockSeqid, lockOwner) {
const openToLockOwner = new structs.Nfsv4OpenToLockOwner(openSeqid, openStateid, lockSeqid, lockOwner);
return new structs.Nfsv4LockOwnerInfo(true, new structs.Nfsv4LockNewOwner(openToLockOwner));
},
ExistingLockOwner(lockStateid, lockSeqid) {
const owner = new structs.Nfsv4LockExistingOwner(lockStateid, lockSeqid);
return new structs.Nfsv4LockOwnerInfo(false, owner);
},
ILLEGAL() {
return new msg.Nfsv4IllegalRequest();
},
};
//# sourceMappingURL=builder.js.map
File diff suppressed because one or more lines are too long
+20
View File
@@ -0,0 +1,20 @@
import type * as misc from 'memfs/lib/node/types/misc';
import type { Nfsv4Client } from './types';
import * as msg from '../messages';
export declare class NfsFsDir implements misc.IDir {
readonly path: string;
private readonly nfs;
private readonly operations;
private entries;
private position;
private closed;
constructor(path: string, nfs: Nfsv4Client, operations: msg.Nfsv4Request[]);
private ensureLoaded;
close(): Promise<void>;
close(callback?: (err?: Error) => void): Promise<void>;
closeSync(): void;
read(): Promise<misc.IDirent | null>;
read(callback?: (err: Error | null, dir?: misc.IDirent | null) => void): Promise<misc.IDirent | null>;
readSync(): misc.IDirent | null;
[Symbol.asyncIterator](): AsyncIterableIterator<misc.IDirent>;
}
+129
View File
@@ -0,0 +1,129 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NfsFsDir = void 0;
const NfsFsDirent_1 = require("./NfsFsDirent");
const builder_1 = require("../builder");
const Reader_1 = require("@jsonjoy.com/buffers/lib/Reader");
const XdrDecoder_1 = require("../../../xdr/XdrDecoder");
class NfsFsDir {
constructor(path, nfs, operations) {
this.path = path;
this.nfs = nfs;
this.operations = operations;
this.entries = [];
this.position = 0;
this.closed = false;
}
async ensureLoaded() {
if (this.entries.length > 0 || this.closed)
return;
const attrNums = [1];
const attrMask = [];
for (const attrNum of attrNums) {
const wordIndex = Math.floor(attrNum / 32);
const bitIndex = attrNum % 32;
while (attrMask.length <= wordIndex)
attrMask.push(0);
attrMask[wordIndex] |= 1 << bitIndex;
}
const operations = [...this.operations];
operations.push(builder_1.nfs.READDIR(attrMask));
const response = await this.nfs.compound(operations);
if (response.status !== 0)
throw new Error(`Failed to read directory: ${response.status}`);
const readdirRes = response.resarray[response.resarray.length - 1];
if (readdirRes.status !== 0 || !readdirRes.resok)
throw new Error(`Failed to read directory: ${readdirRes.status}`);
const entryList = readdirRes.resok.entries;
for (let i = 0; i < entryList.length; i++) {
const entry = entryList[i];
const name = entry.name;
const fattr = entry.attrs;
const reader = new Reader_1.Reader();
reader.reset(fattr.attrVals);
const xdr = new XdrDecoder_1.XdrDecoder(reader);
let fileType = 1;
const returnedMask = fattr.attrmask.mask;
for (let i = 0; i < returnedMask.length; i++) {
const word = returnedMask[i];
if (!word)
continue;
for (let bit = 0; bit < 32; bit++) {
if (!(word & (1 << bit)))
continue;
const attrNum = i * 32 + bit;
if (attrNum === 1) {
fileType = xdr.readUnsignedInt();
}
}
}
this.entries.push(new NfsFsDirent_1.NfsFsDirent(name, fileType));
}
}
async close(callback) {
this.closed = true;
this.entries = [];
this.position = 0;
if (callback) {
try {
callback();
}
catch (err) {
callback(err);
}
}
}
closeSync() {
this.closed = true;
this.entries = [];
this.position = 0;
}
async read(callback) {
try {
if (this.closed) {
const err = new Error('Directory is closed');
if (callback) {
callback(err, null);
return null;
}
throw err;
}
await this.ensureLoaded();
if (this.position >= this.entries.length) {
if (callback) {
callback(null, null);
}
return null;
}
const entry = this.entries[this.position++];
if (callback) {
callback(null, entry);
}
return entry;
}
catch (err) {
if (callback) {
callback(err, null);
return null;
}
throw err;
}
}
readSync() {
if (this.closed) {
throw new Error('Directory is closed');
}
if (this.position >= this.entries.length) {
return null;
}
return this.entries[this.position++];
}
async *[Symbol.asyncIterator]() {
await this.ensureLoaded();
for (const entry of this.entries) {
yield entry;
}
}
}
exports.NfsFsDir = NfsFsDir;
//# sourceMappingURL=NfsFsDir.js.map
@@ -0,0 +1 @@
{"version":3,"file":"NfsFsDir.js","sourceRoot":"","sources":["../../../../src/nfs/v4/client/NfsFsDir.ts"],"names":[],"mappings":"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"}
+14
View File
@@ -0,0 +1,14 @@
import type * as misc from 'memfs/lib/node/types/misc';
import { Nfsv4FType } from '../constants';
export declare class NfsFsDirent implements misc.IDirent {
name: string;
private type;
constructor(name: string, type: Nfsv4FType);
isDirectory(): boolean;
isFile(): boolean;
isBlockDevice(): boolean;
isCharacterDevice(): boolean;
isSymbolicLink(): boolean;
isFIFO(): boolean;
isSocket(): boolean;
}
+32
View File
@@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NfsFsDirent = void 0;
class NfsFsDirent {
constructor(name, type) {
this.name = name;
this.type = type;
}
isDirectory() {
return this.type === 2;
}
isFile() {
return this.type === 1;
}
isBlockDevice() {
return this.type === 3;
}
isCharacterDevice() {
return this.type === 4;
}
isSymbolicLink() {
return this.type === 5;
}
isFIFO() {
return this.type === 7;
}
isSocket() {
return this.type === 6;
}
}
exports.NfsFsDirent = NfsFsDirent;
//# sourceMappingURL=NfsFsDirent.js.map
@@ -0,0 +1 @@
{"version":3,"file":"NfsFsDirent.js","sourceRoot":"","sources":["../../../../src/nfs/v4/client/NfsFsDirent.ts"],"names":[],"mappings":";;;AAMA,MAAa,WAAW;IACtB,YACS,IAAY,EACX,IAAgB;QADjB,SAAI,GAAJ,IAAI,CAAQ;QACX,SAAI,GAAJ,IAAI,CAAY;IACvB,CAAC;IAEJ,WAAW;QACT,OAAO,IAAI,CAAC,IAAI,MAAsB,CAAC;IACzC,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,IAAI,MAAsB,CAAC;IACzC,CAAC;IAED,aAAa;QACX,OAAO,IAAI,CAAC,IAAI,MAAsB,CAAC;IACzC,CAAC;IAED,iBAAiB;QACf,OAAO,IAAI,CAAC,IAAI,MAAsB,CAAC;IACzC,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,CAAC,IAAI,MAAsB,CAAC;IACzC,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,IAAI,MAAuB,CAAC;IAC1C,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,IAAI,MAAuB,CAAC;IAC1C,CAAC;CACF;AAjCD,kCAiCC"}
@@ -0,0 +1,34 @@
/// <reference types="node" />
/// <reference types="node" />
import { EventEmitter } from 'events';
import * as structs from '../structs';
import type * as misc from 'memfs/lib/node/types/misc';
import type * as opts from 'memfs/lib/node/types/options';
import type { Nfsv4FsClient } from './Nfsv4FsClient';
export declare class NfsFsFileHandle extends EventEmitter implements misc.IFileHandle {
readonly path: string;
private readonly client;
private readonly stateid;
private readonly openOwner;
readonly fd: number;
private closed;
constructor(fd: number, path: string, client: Nfsv4FsClient, stateid: structs.Nfsv4Stateid, openOwner: structs.Nfsv4OpenOwner);
getAsyncId(): number;
close(): Promise<void>;
stat(options?: opts.IStatOptions): Promise<misc.IStats>;
appendFile(data: misc.TData, options?: opts.IAppendFileOptions | string): Promise<void>;
chmod(mode: misc.TMode): Promise<void>;
chown(uid: number, gid: number): Promise<void>;
datasync(): Promise<void>;
read(buffer: Buffer | Uint8Array, offset: number, length: number, position?: number | null): Promise<misc.TFileHandleReadResult>;
readFile(options?: opts.IReadFileOptions | string): Promise<misc.TDataOut>;
truncate(len?: number): Promise<void>;
utimes(atime: misc.TTime, mtime: misc.TTime): Promise<void>;
write(buffer: Buffer | ArrayBufferView | DataView, offset?: number, length?: number, position?: number | null): Promise<misc.TFileHandleWriteResult>;
writeFile(data: misc.TData, options?: opts.IWriteFileOptions): Promise<void>;
readv(buffers: ArrayBufferView[], position?: number | null): Promise<misc.TFileHandleReadvResult>;
writev(buffers: ArrayBufferView[], position?: number | null): Promise<misc.TFileHandleWritevResult>;
readableWebStream(options?: opts.IReadableWebStreamOptions): ReadableStream;
createReadStream(options?: opts.IFileHandleReadStreamOptions): misc.IReadStream;
createWriteStream(options?: opts.IFileHandleWriteStreamOptions): misc.IWriteStream;
}
@@ -0,0 +1,268 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NfsFsFileHandle = void 0;
const events_1 = require("events");
const stream_1 = require("stream");
const builder_1 = require("../builder");
class NfsFsFileHandle extends events_1.EventEmitter {
constructor(fd, path, client, stateid, openOwner) {
super();
this.path = path;
this.client = client;
this.stateid = stateid;
this.openOwner = openOwner;
this.closed = false;
this.fd = fd;
}
getAsyncId() {
return this.fd;
}
async close() {
if (this.closed)
return;
this.closed = true;
await this.client.closeStateid(this.openOwner, this.stateid);
this.emit('close');
}
async stat(options) {
if (this.closed)
throw new Error('File handle is closed');
return this.client.stat(this.path, options);
}
async appendFile(data, options) {
if (this.closed)
throw new Error('File handle is closed');
return this.client.appendFile(this.path, data, options);
}
async chmod(mode) {
if (this.closed)
throw new Error('File handle is closed');
return this.client.chmod(this.path, mode);
}
async chown(uid, gid) {
if (this.closed)
throw new Error('File handle is closed');
return this.client.chown(this.path, uid, gid);
}
async datasync() {
if (this.closed)
throw new Error('File handle is closed');
}
async read(buffer, offset, length, position) {
if (this.closed)
throw new Error('File handle is closed');
const readPos = position !== null && position !== undefined ? BigInt(position) : BigInt(0);
const readOps = [builder_1.nfs.READ(readPos, length, this.stateid)];
const response = await this.client.fs.compound(readOps);
if (response.status !== 0) {
throw new Error(`Failed to read file: ${response.status}`);
}
const readRes = response.resarray[0];
if (readRes.status !== 0 || !readRes.resok) {
throw new Error(`Failed to read file: ${readRes.status}`);
}
const data = readRes.resok.data;
const bytesToCopy = Math.min(data.length, length);
for (let i = 0; i < bytesToCopy; i++) {
buffer[offset + i] = data[i];
}
return { bytesRead: bytesToCopy, buffer };
}
async readFile(options) {
if (this.closed)
throw new Error('File handle is closed');
return this.client.readFile(this.path, options);
}
async truncate(len) {
if (this.closed)
throw new Error('File handle is closed');
return this.client.truncate(this.path, len);
}
async utimes(atime, mtime) {
if (this.closed)
throw new Error('File handle is closed');
return this.client.utimes(this.path, atime, mtime);
}
async write(buffer, offset, length, position) {
if (this.closed)
throw new Error('File handle is closed');
const actualOffset = offset ?? 0;
const actualLength = length ?? buffer.byteLength - actualOffset;
const writePos = position !== null && position !== undefined ? BigInt(position) : BigInt(0);
let data;
if (buffer instanceof Uint8Array) {
data = Uint8Array.prototype.slice.call(buffer, actualOffset, actualOffset + actualLength);
}
else if (Buffer.isBuffer(buffer)) {
data = new Uint8Array(buffer.buffer, buffer.byteOffset + actualOffset, actualLength);
}
else if (buffer instanceof DataView) {
data = new Uint8Array(buffer.buffer, buffer.byteOffset + actualOffset, actualLength);
}
else {
data = new Uint8Array(buffer.buffer, buffer.byteOffset + actualOffset, actualLength);
}
const writeOps = [builder_1.nfs.WRITE(this.stateid, writePos, 2, data)];
const response = await this.client.fs.compound(writeOps);
if (response.status !== 0) {
throw new Error(`Failed to write file: ${response.status}`);
}
const writeRes = response.resarray[0];
if (writeRes.status !== 0 || !writeRes.resok) {
throw new Error(`Failed to write file: ${writeRes.status}`);
}
const resultBuffer = buffer instanceof Uint8Array || Buffer.isBuffer(buffer) ? buffer : new Uint8Array(buffer.buffer);
return { bytesWritten: writeRes.resok.count, buffer: resultBuffer };
}
async writeFile(data, options) {
if (this.closed)
throw new Error('File handle is closed');
return this.client.writeFile(this.path, data, options);
}
async readv(buffers, position) {
if (this.closed)
throw new Error('File handle is closed');
let currentPosition = position !== null && position !== undefined ? BigInt(position) : BigInt(0);
let totalBytesRead = 0;
for (const buffer of buffers) {
const readOps = [builder_1.nfs.READ(currentPosition, buffer.byteLength, this.stateid)];
const response = await this.client.fs.compound(readOps);
if (response.status !== 0) {
throw new Error(`Failed to read file: ${response.status}`);
}
const readRes = response.resarray[0];
if (readRes.status !== 0 || !readRes.resok) {
throw new Error(`Failed to read file: ${readRes.status}`);
}
const data = readRes.resok.data;
const bytesToCopy = Math.min(data.length, buffer.byteLength);
const uint8View = new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
for (let i = 0; i < bytesToCopy; i++) {
uint8View[i] = data[i];
}
totalBytesRead += bytesToCopy;
currentPosition += BigInt(bytesToCopy);
if (readRes.resok.eof || bytesToCopy < buffer.byteLength)
break;
}
return { bytesRead: totalBytesRead, buffers };
}
async writev(buffers, position) {
if (this.closed)
throw new Error('File handle is closed');
let currentPosition = position !== null && position !== undefined ? BigInt(position) : BigInt(0);
let totalBytesWritten = 0;
for (const buffer of buffers) {
const data = new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
const writeOps = [builder_1.nfs.WRITE(this.stateid, currentPosition, 2, data)];
const response = await this.client.fs.compound(writeOps);
if (response.status !== 0) {
throw new Error(`Failed to write file: ${response.status}`);
}
const writeRes = response.resarray[0];
if (writeRes.status !== 0 || !writeRes.resok) {
throw new Error(`Failed to write file: ${writeRes.status}`);
}
totalBytesWritten += writeRes.resok.count;
currentPosition += BigInt(writeRes.resok.count);
}
return { bytesWritten: totalBytesWritten, buffers };
}
readableWebStream(options) {
if (this.closed)
throw new Error('File handle is closed');
const stream = this.createReadStream(options);
return stream_1.Readable.toWeb(stream);
}
createReadStream(options) {
if (this.closed)
throw new Error('File handle is closed');
const start = options?.start ?? 0;
const end = options?.end;
const highWaterMark = options?.highWaterMark ?? 64 * 1024;
let position = typeof start === 'number' ? start : 0;
const endPosition = typeof end === 'number' ? end : Infinity;
let reading = false;
const self = this;
const stream = new stream_1.Readable({
highWaterMark,
async read(size) {
if (reading)
return;
reading = true;
try {
while (true) {
if (position >= endPosition) {
this.push(null);
break;
}
const bytesToRead = Math.min(size, endPosition - position);
if (bytesToRead <= 0) {
this.push(null);
break;
}
const buffer = Buffer.alloc(bytesToRead);
const result = await self.read(buffer, 0, bytesToRead, position);
if (result.bytesRead === 0) {
this.push(null);
break;
}
position += result.bytesRead;
const chunk = buffer.slice(0, result.bytesRead);
if (!this.push(chunk))
break;
if (result.bytesRead < bytesToRead) {
this.push(null);
break;
}
}
}
catch (err) {
this.destroy(err);
}
finally {
reading = false;
}
},
});
stream.path = this.path;
return stream;
}
createWriteStream(options) {
if (this.closed)
throw new Error('File handle is closed');
const start = options?.start ?? 0;
const highWaterMark = options?.highWaterMark ?? 64 * 1024;
let position = typeof start === 'number' ? start : 0;
const self = this;
const stream = new stream_1.Writable({
highWaterMark,
async write(chunk, encoding, callback) {
try {
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
const result = await self.write(buffer, 0, buffer.length, position);
position += result.bytesWritten;
callback();
}
catch (err) {
callback(err);
}
},
async writev(chunks, callback) {
try {
const buffers = chunks.map(({ chunk }) => (Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));
const result = await self.writev(buffers, position);
position += result.bytesWritten;
callback();
}
catch (err) {
callback(err);
}
},
});
stream.path = this.path;
return stream;
}
}
exports.NfsFsFileHandle = NfsFsFileHandle;
//# sourceMappingURL=NfsFsFileHandle.js.map
File diff suppressed because one or more lines are too long
+31
View File
@@ -0,0 +1,31 @@
import type * as misc from 'memfs/lib/node/types/misc';
import { Nfsv4FType } from '../constants';
export declare class NfsFsStats implements misc.IStats<number> {
uid: number;
gid: number;
rdev: number;
blksize: number;
ino: number;
size: number;
blocks: number;
atime: Date;
mtime: Date;
ctime: Date;
birthtime: Date;
atimeMs: number;
mtimeMs: number;
ctimeMs: number;
birthtimeMs: number;
dev: number;
mode: number;
nlink: number;
private type;
constructor(uid: number, gid: number, rdev: number, blksize: number, ino: number, size: number, blocks: number, atime: Date, mtime: Date, ctime: Date, birthtime: Date, atimeMs: number, mtimeMs: number, ctimeMs: number, birthtimeMs: number, dev: number, mode: number, nlink: number, type: Nfsv4FType);
isDirectory(): boolean;
isFile(): boolean;
isBlockDevice(): boolean;
isCharacterDevice(): boolean;
isSymbolicLink(): boolean;
isFIFO(): boolean;
isSocket(): boolean;
}
+49
View File
@@ -0,0 +1,49 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NfsFsStats = void 0;
class NfsFsStats {
constructor(uid, gid, rdev, blksize, ino, size, blocks, atime, mtime, ctime, birthtime, atimeMs, mtimeMs, ctimeMs, birthtimeMs, dev, mode, nlink, type) {
this.uid = uid;
this.gid = gid;
this.rdev = rdev;
this.blksize = blksize;
this.ino = ino;
this.size = size;
this.blocks = blocks;
this.atime = atime;
this.mtime = mtime;
this.ctime = ctime;
this.birthtime = birthtime;
this.atimeMs = atimeMs;
this.mtimeMs = mtimeMs;
this.ctimeMs = ctimeMs;
this.birthtimeMs = birthtimeMs;
this.dev = dev;
this.mode = mode;
this.nlink = nlink;
this.type = type;
}
isDirectory() {
return this.type === 2;
}
isFile() {
return this.type === 1;
}
isBlockDevice() {
return this.type === 3;
}
isCharacterDevice() {
return this.type === 4;
}
isSymbolicLink() {
return this.type === 5;
}
isFIFO() {
return this.type === 7;
}
isSocket() {
return this.type === 6;
}
}
exports.NfsFsStats = NfsFsStats;
//# sourceMappingURL=NfsFsStats.js.map
@@ -0,0 +1 @@
{"version":3,"file":"NfsFsStats.js","sourceRoot":"","sources":["../../../../src/nfs/v4/client/NfsFsStats.ts"],"names":[],"mappings":";;;AAMA,MAAa,UAAU;IACrB,YACS,GAAW,EACX,GAAW,EACX,IAAY,EACZ,OAAe,EACf,GAAW,EACX,IAAY,EACZ,MAAc,EACd,KAAW,EACX,KAAW,EACX,KAAW,EACX,SAAe,EACf,OAAe,EACf,OAAe,EACf,OAAe,EACf,WAAmB,EACnB,GAAW,EACX,IAAY,EACZ,KAAa,EACZ,IAAgB;QAlBjB,QAAG,GAAH,GAAG,CAAQ;QACX,QAAG,GAAH,GAAG,CAAQ;QACX,SAAI,GAAJ,IAAI,CAAQ;QACZ,YAAO,GAAP,OAAO,CAAQ;QACf,QAAG,GAAH,GAAG,CAAQ;QACX,SAAI,GAAJ,IAAI,CAAQ;QACZ,WAAM,GAAN,MAAM,CAAQ;QACd,UAAK,GAAL,KAAK,CAAM;QACX,UAAK,GAAL,KAAK,CAAM;QACX,UAAK,GAAL,KAAK,CAAM;QACX,cAAS,GAAT,SAAS,CAAM;QACf,YAAO,GAAP,OAAO,CAAQ;QACf,YAAO,GAAP,OAAO,CAAQ;QACf,YAAO,GAAP,OAAO,CAAQ;QACf,gBAAW,GAAX,WAAW,CAAQ;QACnB,QAAG,GAAH,GAAG,CAAQ;QACX,SAAI,GAAJ,IAAI,CAAQ;QACZ,UAAK,GAAL,KAAK,CAAQ;QACZ,SAAI,GAAJ,IAAI,CAAY;IACvB,CAAC;IAEJ,WAAW;QACT,OAAO,IAAI,CAAC,IAAI,MAAsB,CAAC;IACzC,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,IAAI,MAAsB,CAAC;IACzC,CAAC;IAED,aAAa;QACX,OAAO,IAAI,CAAC,IAAI,MAAsB,CAAC;IACzC,CAAC;IAED,iBAAiB;QACf,OAAO,IAAI,CAAC,IAAI,MAAsB,CAAC;IACzC,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,CAAC,IAAI,MAAsB,CAAC;IACzC,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,IAAI,MAAuB,CAAC;IAC1C,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,IAAI,MAAuB,CAAC;IAC1C,CAAC;CACF;AAlDD,gCAkDC"}
@@ -0,0 +1,54 @@
/// <reference types="node" />
import type { NfsFsClient, Nfsv4Client } from './types';
import * as misc from 'memfs/lib/node/types/misc';
import * as opts from 'memfs/lib/node/types/options';
import * as structs from '../structs';
export declare class Nfsv4FsClient implements NfsFsClient {
readonly fs: Nfsv4Client;
constructor(fs: Nfsv4Client);
private readonly openOwnerSeqids;
private readonly defaultOpenOwnerId;
private makeOpenOwnerKey;
private nextOpenOwnerSeqid;
private createDefaultOpenOwner;
private attrNumsToBitmap;
private parsePath;
private navigateToParent;
private navigateToPath;
private encodeData;
private decodeData;
readonly closeStateid: (openOwner: structs.Nfsv4OpenOwner, stateid: structs.Nfsv4Stateid) => Promise<void>;
readonly readFile: (id: misc.TFileHandle, options?: opts.IReadFileOptions | string) => Promise<misc.TDataOut>;
readonly writeFile: (id: misc.TFileHandle, data: misc.TPromisesData, options?: opts.IWriteFileOptions) => Promise<void>;
readonly stat: (path: misc.PathLike, options?: opts.IStatOptions) => Promise<misc.IStats>;
readonly lstat: (path: misc.PathLike, options?: opts.IStatOptions) => Promise<misc.IStats>;
readonly mkdir: (path: misc.PathLike, options?: misc.TMode | opts.IMkdirOptions) => Promise<string | undefined>;
readonly readdir: (path: misc.PathLike, options?: opts.IReaddirOptions | string) => Promise<misc.TDataOut[] | misc.IDirent[]>;
readonly appendFile: (path: misc.TFileHandle, data: misc.TData, options?: opts.IAppendFileOptions | string) => Promise<void>;
readonly truncate: (path: misc.PathLike, len?: number) => Promise<void>;
readonly unlink: (path: misc.PathLike) => Promise<void>;
readonly rmdir: (path: misc.PathLike, options?: opts.IRmdirOptions) => Promise<void>;
readonly rm: (path: misc.PathLike, options?: opts.IRmOptions) => Promise<void>;
readonly access: (path: misc.PathLike, mode?: number) => Promise<void>;
readonly rename: (oldPath: misc.PathLike, newPath: misc.PathLike) => Promise<void>;
readonly copyFile: (src: misc.PathLike, dest: misc.PathLike, flags?: misc.TFlagsCopy) => Promise<void>;
readonly realpath: (path: misc.PathLike, options?: opts.IRealpathOptions | string) => Promise<misc.TDataOut>;
readonly link: (existingPath: misc.PathLike, newPath: misc.PathLike) => Promise<void>;
readonly symlink: (target: misc.PathLike, path: misc.PathLike, type?: misc.symlink.Type) => Promise<void>;
readonly utimes: (path: misc.PathLike, atime: misc.TTime, mtime: misc.TTime) => Promise<void>;
readonly readlink: (path: misc.PathLike, options?: opts.IOptions) => Promise<misc.TDataOut>;
readonly opendir: (path: misc.PathLike, options?: opts.IOpendirOptions) => Promise<misc.IDir>;
readonly mkdtemp: (prefix: string, options?: opts.IOptions) => Promise<misc.TDataOut>;
readonly chmod: (path: misc.PathLike, mode: misc.TMode) => Promise<void>;
readonly chown: (path: misc.PathLike, uid: number, gid: number) => Promise<void>;
readonly lchmod: (path: misc.PathLike, mode: misc.TMode) => Promise<void>;
readonly lchown: (path: misc.PathLike, uid: number, gid: number) => Promise<void>;
readonly lutimes: (path: misc.PathLike, atime: misc.TTime, mtime: misc.TTime) => Promise<void>;
readonly open: (path: misc.PathLike, flags?: misc.TFlags, mode?: misc.TMode) => Promise<misc.IFileHandle>;
readonly statfs: (path: misc.PathLike, options?: opts.IStatOptions) => Promise<misc.IStatFs>;
readonly watch: (filename: misc.PathLike, options?: opts.IWatchOptions) => AsyncIterableIterator<{
eventType: string;
filename: string | Buffer;
}>;
readonly glob: (pattern: string, options?: opts.IGlobOptions) => Promise<string[]>;
}
+812
View File
@@ -0,0 +1,812 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Nfsv4FsClient = void 0;
const tslib_1 = require("tslib");
const builder_1 = require("../builder");
const structs = tslib_1.__importStar(require("../structs"));
const Writer_1 = require("@jsonjoy.com/buffers/lib/Writer");
const Reader_1 = require("@jsonjoy.com/buffers/lib/Reader");
const XdrEncoder_1 = require("../../../xdr/XdrEncoder");
const XdrDecoder_1 = require("../../../xdr/XdrDecoder");
const NfsFsStats_1 = require("./NfsFsStats");
const NfsFsDir_1 = require("./NfsFsDir");
const NfsFsDirent_1 = require("./NfsFsDirent");
const NfsFsFileHandle_1 = require("./NfsFsFileHandle");
class Nfsv4FsClient {
constructor(fs) {
this.fs = fs;
this.openOwnerSeqids = new Map();
this.defaultOpenOwnerId = new Uint8Array([1, 2, 3, 4]);
this.closeStateid = async (openOwner, stateid) => {
const key = this.makeOpenOwnerKey(openOwner);
const previousSeqid = this.openOwnerSeqids.get(key);
const seqid = this.nextOpenOwnerSeqid(openOwner);
const response = await this.fs.compound([builder_1.nfs.CLOSE(seqid, stateid)]);
if (response.status !== 0) {
if (previousSeqid !== undefined) {
this.openOwnerSeqids.set(key, previousSeqid);
}
else {
this.openOwnerSeqids.delete(key);
}
throw new Error(`Failed to close file: ${response.status}`);
}
};
this.readFile = async (id, options) => {
const encoding = typeof options === 'string' ? options : options?.encoding;
const path = typeof id === 'string' ? id : id.toString();
const parts = this.parsePath(path);
const operations = this.navigateToParent(parts);
const filename = parts[parts.length - 1];
const openOwner = this.createDefaultOpenOwner();
const claim = builder_1.nfs.OpenClaimNull(filename);
const openSeqid = this.nextOpenOwnerSeqid(openOwner);
operations.push(builder_1.nfs.OPEN(openSeqid, 1, 0, openOwner, builder_1.nfs.OpenHowNoCreate(), claim));
const openResponse = await this.fs.compound(operations);
if (openResponse.status !== 0) {
throw new Error(`Failed to open file: ${openResponse.status}`);
}
const openRes = openResponse.resarray[openResponse.resarray.length - 1];
if (openRes.status !== 0 || !openRes.resok) {
throw new Error(`Failed to open file: ${openRes.status}`);
}
const stateid = openRes.resok.stateid;
const chunks = [];
let offset = BigInt(0);
const chunkSize = 65536;
try {
while (true) {
const readResponse = await this.fs.compound([builder_1.nfs.READ(offset, chunkSize, stateid)]);
if (readResponse.status !== 0) {
throw new Error(`Failed to read file: ${readResponse.status}`);
}
const readRes = readResponse.resarray[0];
if (readRes.status !== 0 || !readRes.resok) {
throw new Error(`Failed to read file: ${readRes.status}`);
}
if (readRes.resok.data.length > 0) {
chunks.push(readRes.resok.data);
offset += BigInt(readRes.resok.data.length);
}
if (readRes.resok.eof)
break;
}
}
finally {
await this.closeStateid(openOwner, stateid);
}
const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
const result = new Uint8Array(totalLength);
let position = 0;
for (const chunk of chunks) {
result.set(chunk, position);
position += chunk.length;
}
return this.decodeData(result, encoding);
};
this.writeFile = async (id, data, options) => {
const path = typeof id === 'string' ? id : id.toString();
const parts = this.parsePath(path);
const operations = this.navigateToParent(parts);
const filename = parts[parts.length - 1];
const openOwner = this.createDefaultOpenOwner();
const claim = builder_1.nfs.OpenClaimNull(filename);
const openSeqid = this.nextOpenOwnerSeqid(openOwner);
operations.push(builder_1.nfs.OPEN(openSeqid, 2, 0, openOwner, builder_1.nfs.OpenHowCreateUnchecked(), claim));
const writer = new Writer_1.Writer(16);
const xdr = new XdrEncoder_1.XdrEncoder(writer);
xdr.writeUnsignedHyper(BigInt(0));
const attrVals = writer.flush();
const truncateAttrs = builder_1.nfs.Fattr([4], attrVals);
const stateid = builder_1.nfs.Stateid(0, new Uint8Array(12));
operations.push(builder_1.nfs.SETATTR(stateid, truncateAttrs));
const openResponse = await this.fs.compound(operations);
if (openResponse.status !== 0) {
throw new Error(`Failed to open file: ${openResponse.status}`);
}
const openRes = openResponse.resarray[openResponse.resarray.length - 2];
if (openRes.status !== 0 || !openRes.resok) {
throw new Error(`Failed to open file: ${openRes.status}`);
}
const openStateid = openRes.resok.stateid;
const buffer = this.encodeData(data);
const chunkSize = 65536;
try {
let offset = BigInt(0);
for (let i = 0; i < buffer.length; i += chunkSize) {
const chunk = buffer.slice(i, Math.min(i + chunkSize, buffer.length));
const writeResponse = await this.fs.compound([
builder_1.nfs.WRITE(openStateid, offset, 2, chunk),
]);
if (writeResponse.status !== 0) {
throw new Error(`Failed to write file: ${writeResponse.status}`);
}
const writeRes = writeResponse.resarray[0];
if (writeRes.status !== 0 || !writeRes.resok) {
throw new Error(`Failed to write file: ${writeRes.status}`);
}
offset += BigInt(writeRes.resok.count);
}
}
finally {
await this.closeStateid(openOwner, openStateid);
}
};
this.stat = async (path, options) => {
const pathStr = typeof path === 'string' ? path : path.toString();
const parts = this.parsePath(pathStr);
const operations = this.navigateToPath(parts);
const attrNums = [
1,
4,
20,
33,
35,
45,
47,
53,
52,
];
const attrMask = this.attrNumsToBitmap(attrNums);
operations.push(builder_1.nfs.GETATTR(attrMask));
const response = await this.fs.compound(operations);
if (response.status !== 0) {
throw new Error(`Failed to stat file: ${response.status}`);
}
const getattrRes = response.resarray[response.resarray.length - 1];
if (getattrRes.status !== 0 || !getattrRes.resok) {
throw new Error(`Failed to get attributes: ${getattrRes.status}`);
}
const fattr = getattrRes.resok.objAttributes;
const reader = new Reader_1.Reader();
reader.reset(fattr.attrVals);
const xdr = new XdrDecoder_1.XdrDecoder(reader);
let fileType = 1;
let size = 0;
let fileid = 0;
let mode = 0;
let nlink = 1;
let spaceUsed = 0;
let atime = new Date(0);
let mtime = new Date(0);
let ctime = new Date(0);
const returnedMask = fattr.attrmask.mask;
for (let i = 0; i < returnedMask.length; i++) {
const word = returnedMask[i];
if (!word)
continue;
for (let bit = 0; bit < 32; bit++) {
if (!(word & (1 << bit)))
continue;
const attrNum = i * 32 + bit;
switch (attrNum) {
case 1:
fileType = xdr.readUnsignedInt();
break;
case 4:
size = Number(xdr.readUnsignedHyper());
break;
case 20:
fileid = Number(xdr.readUnsignedHyper());
break;
case 33:
mode = xdr.readUnsignedInt();
break;
case 35:
nlink = xdr.readUnsignedInt();
break;
case 45:
spaceUsed = Number(xdr.readUnsignedHyper());
break;
case 47: {
const seconds = Number(xdr.readHyper());
const nseconds = xdr.readUnsignedInt();
atime = new Date(seconds * 1000 + nseconds / 1000000);
break;
}
case 53: {
const seconds = Number(xdr.readHyper());
const nseconds = xdr.readUnsignedInt();
mtime = new Date(seconds * 1000 + nseconds / 1000000);
break;
}
case 52: {
const seconds = Number(xdr.readHyper());
const nseconds = xdr.readUnsignedInt();
ctime = new Date(seconds * 1000 + nseconds / 1000000);
break;
}
}
}
}
const blocks = Math.ceil(spaceUsed / 512);
return new NfsFsStats_1.NfsFsStats(0, 0, 0, 4096, fileid, size, blocks, atime, mtime, ctime, mtime, atime.getTime(), mtime.getTime(), ctime.getTime(), mtime.getTime(), 0, mode, nlink, fileType);
};
this.lstat = async (path, options) => {
return this.stat(path, options);
};
this.mkdir = async (path, options) => {
const pathStr = typeof path === 'string' ? path : path.toString();
const parts = this.parsePath(pathStr);
if (parts.length === 0) {
throw new Error('Cannot create root directory');
}
const operations = this.navigateToParent(parts);
const dirname = parts[parts.length - 1];
const createType = builder_1.nfs.CreateTypeDir();
const emptyAttrs = builder_1.nfs.Fattr([], new Uint8Array(0));
operations.push(builder_1.nfs.CREATE(createType, dirname, emptyAttrs));
const response = await this.fs.compound(operations);
if (response.status !== 0) {
throw new Error(`Failed to create directory: ${response.status}`);
}
const createRes = response.resarray[response.resarray.length - 1];
if (createRes.status !== 0) {
throw new Error(`Failed to create directory: ${createRes.status}`);
}
return undefined;
};
this.readdir = async (path, options) => {
const pathStr = typeof path === 'string' ? path : path.toString();
const withFileTypes = typeof options === 'object' && options?.withFileTypes;
const encoding = typeof options === 'string' ? options : options?.encoding;
const parts = this.parsePath(pathStr);
const operations = this.navigateToPath(parts);
const attrNums = withFileTypes ? [1] : [];
const attrMask = this.attrNumsToBitmap(attrNums);
operations.push(builder_1.nfs.READDIR(attrMask));
const response = await this.fs.compound(operations);
if (response.status !== 0) {
throw new Error(`Failed to read directory: ${response.status}`);
}
const readdirRes = response.resarray[response.resarray.length - 1];
if (readdirRes.status !== 0 || !readdirRes.resok) {
throw new Error(`Failed to read directory: ${readdirRes.status}`);
}
const entries = [];
const dirents = [];
const entryList = readdirRes.resok.entries;
for (let i = 0; i < entryList.length; i++) {
const entry = entryList[i];
const name = entry.name;
if (withFileTypes) {
const fattr = entry.attrs;
const reader = new Reader_1.Reader();
reader.reset(fattr.attrVals);
const xdr = new XdrDecoder_1.XdrDecoder(reader);
let fileType = 1;
const returnedMask = fattr.attrmask.mask;
for (let i = 0; i < returnedMask.length; i++) {
const word = returnedMask[i];
if (!word)
continue;
for (let bit = 0; bit < 32; bit++) {
if (!(word & (1 << bit)))
continue;
const attrNum = i * 32 + bit;
if (attrNum === 1) {
fileType = xdr.readUnsignedInt();
}
}
}
dirents.push(new NfsFsDirent_1.NfsFsDirent(name, fileType));
}
else {
entries.push(name);
}
}
if (withFileTypes) {
return dirents;
}
if (encoding && encoding !== 'utf8') {
return entries.map((name) => Buffer.from(name, 'utf8'));
}
return entries;
};
this.appendFile = async (path, data, options) => {
const pathStr = typeof path === 'string' ? path : path.toString();
const parts = this.parsePath(pathStr);
const operations = this.navigateToParent(parts);
const filename = parts[parts.length - 1];
const openOwner = this.createDefaultOpenOwner();
const claim = builder_1.nfs.OpenClaimNull(filename);
const openSeqid = this.nextOpenOwnerSeqid(openOwner);
operations.push(builder_1.nfs.OPEN(openSeqid, 2, 0, openOwner, builder_1.nfs.OpenHowNoCreate(), claim));
const attrNums = [4];
const attrMask = this.attrNumsToBitmap(attrNums);
operations.push(builder_1.nfs.GETATTR(attrMask));
const openResponse = await this.fs.compound(operations);
if (openResponse.status !== 0) {
throw new Error(`Failed to open file: ${openResponse.status}`);
}
const openRes = openResponse.resarray[openResponse.resarray.length - 2];
if (openRes.status !== 0 || !openRes.resok) {
throw new Error(`Failed to open file: ${openRes.status}`);
}
const getattrRes = openResponse.resarray[openResponse.resarray.length - 1];
if (getattrRes.status !== 0 || !getattrRes.resok) {
throw new Error(`Failed to get attributes: ${getattrRes.status}`);
}
const fattr = getattrRes.resok.objAttributes;
const reader = new Reader_1.Reader();
reader.reset(fattr.attrVals);
const xdr = new XdrDecoder_1.XdrDecoder(reader);
const currentSize = Number(xdr.readUnsignedHyper());
const openStateid = openRes.resok.stateid;
const buffer = this.encodeData(data);
const chunkSize = 65536;
try {
let offset = BigInt(currentSize);
for (let i = 0; i < buffer.length; i += chunkSize) {
const chunk = buffer.slice(i, Math.min(i + chunkSize, buffer.length));
const writeResponse = await this.fs.compound([
builder_1.nfs.WRITE(openStateid, offset, 2, chunk),
]);
if (writeResponse.status !== 0) {
throw new Error(`Failed to write file: ${writeResponse.status}`);
}
const writeRes = writeResponse.resarray[0];
if (writeRes.status !== 0 || !writeRes.resok) {
throw new Error(`Failed to write file: ${writeRes.status}`);
}
offset += BigInt(writeRes.resok.count);
}
}
finally {
await this.closeStateid(openOwner, openStateid);
}
};
this.truncate = async (path, len = 0) => {
const pathStr = typeof path === 'string' ? path : path.toString();
const parts = this.parsePath(pathStr);
const operations = this.navigateToPath(parts);
const writer = new Writer_1.Writer(16);
const xdr = new XdrEncoder_1.XdrEncoder(writer);
xdr.writeUnsignedHyper(BigInt(len));
const attrVals = writer.flush();
const sizeAttrs = builder_1.nfs.Fattr([4], attrVals);
const stateid = builder_1.nfs.Stateid(0, new Uint8Array(12));
operations.push(builder_1.nfs.SETATTR(stateid, sizeAttrs));
const response = await this.fs.compound(operations);
if (response.status !== 0) {
throw new Error(`Failed to truncate file: ${response.status}`);
}
const setattrRes = response.resarray[response.resarray.length - 1];
if (setattrRes.status !== 0) {
throw new Error(`Failed to truncate file: ${setattrRes.status}`);
}
};
this.unlink = async (path) => {
const pathStr = typeof path === 'string' ? path : path.toString();
const parts = this.parsePath(pathStr);
if (parts.length === 0) {
throw new Error('Cannot unlink root directory');
}
const operations = this.navigateToParent(parts);
const filename = parts[parts.length - 1];
operations.push(builder_1.nfs.REMOVE(filename));
const response = await this.fs.compound(operations);
if (response.status !== 0) {
throw new Error(`Failed to unlink file: ${response.status}`);
}
const removeRes = response.resarray[response.resarray.length - 1];
if (removeRes.status !== 0) {
throw new Error(`Failed to unlink file: ${removeRes.status}`);
}
};
this.rmdir = async (path, options) => {
const pathStr = typeof path === 'string' ? path : path.toString();
const parts = this.parsePath(pathStr);
if (parts.length === 0) {
throw new Error('Cannot remove root directory');
}
const operations = this.navigateToParent(parts);
const dirname = parts[parts.length - 1];
operations.push(builder_1.nfs.REMOVE(dirname));
const response = await this.fs.compound(operations);
if (response.status !== 0) {
throw new Error(`Failed to remove directory: ${response.status}`);
}
const removeRes = response.resarray[response.resarray.length - 1];
if (removeRes.status !== 0) {
throw new Error(`Failed to remove directory: ${removeRes.status}`);
}
};
this.rm = async (path, options) => {
const pathStr = typeof path === 'string' ? path : path.toString();
const parts = this.parsePath(pathStr);
if (parts.length === 0) {
throw new Error('Cannot remove root directory');
}
const force = options?.force ?? false;
const recursive = options?.recursive ?? false;
if (recursive) {
try {
const stats = await this.stat(path);
if (stats.isDirectory()) {
const entries = await this.readdir(path);
for (const entry of entries) {
const entryPath = pathStr + '/' + entry;
await this.rm(entryPath, options);
}
}
}
catch (err) {
if (!force)
throw err;
return;
}
}
try {
const operations = this.navigateToParent(parts);
const name = parts[parts.length - 1];
operations.push(builder_1.nfs.REMOVE(name));
const response = await this.fs.compound(operations);
if (response.status !== 0) {
if (!force)
throw new Error(`Failed to remove: ${response.status}`);
return;
}
const removeRes = response.resarray[response.resarray.length - 1];
if (removeRes.status !== 0) {
if (!force)
throw new Error(`Failed to remove: ${removeRes.status}`);
}
}
catch (err) {
if (!force)
throw err;
}
};
this.access = async (path, mode = 0) => {
const pathStr = typeof path === 'string' ? path : path.toString();
const parts = this.parsePath(pathStr);
const operations = this.navigateToPath(parts);
let accessMask = 0;
if (mode === 0) {
accessMask = 1;
}
else {
if (mode & 4)
accessMask |= 1;
if (mode & 2)
accessMask |= 4;
if (mode & 1)
accessMask |= 32;
}
operations.push(builder_1.nfs.ACCESS(accessMask));
const response = await this.fs.compound(operations);
if (response.status !== 0) {
throw new Error(`Access denied: ${response.status}`);
}
const accessRes = response.resarray[response.resarray.length - 1];
if (accessRes.status !== 0) {
throw new Error(`Access denied: ${accessRes.status}`);
}
};
this.rename = async (oldPath, newPath) => {
const oldPathStr = typeof oldPath === 'string' ? oldPath : oldPath.toString();
const newPathStr = typeof newPath === 'string' ? newPath : newPath.toString();
const oldParts = this.parsePath(oldPathStr);
const newParts = this.parsePath(newPathStr);
if (oldParts.length === 0 || newParts.length === 0) {
throw new Error('Cannot rename root directory');
}
const operations = [];
operations.push(builder_1.nfs.PUTROOTFH());
for (const part of oldParts.slice(0, -1)) {
operations.push(builder_1.nfs.LOOKUP(part));
}
operations.push(builder_1.nfs.SAVEFH());
operations.push(builder_1.nfs.PUTROOTFH());
for (const part of newParts.slice(0, -1)) {
operations.push(builder_1.nfs.LOOKUP(part));
}
const oldname = oldParts[oldParts.length - 1];
const newname = newParts[newParts.length - 1];
operations.push(builder_1.nfs.RENAME(oldname, newname));
const response = await this.fs.compound(operations);
if (response.status !== 0) {
throw new Error(`Failed to rename: ${response.status}`);
}
const renameRes = response.resarray[response.resarray.length - 1];
if (renameRes.status !== 0) {
throw new Error(`Failed to rename: ${renameRes.status}`);
}
};
this.copyFile = async (src, dest, flags) => {
const data = await this.readFile(src);
await this.writeFile(dest, data);
};
this.realpath = async (path, options) => {
const encoding = typeof options === 'string' ? options : options?.encoding;
const pathStr = typeof path === 'string' ? path : path.toString();
const normalized = '/' + this.parsePath(pathStr).join('/');
if (!encoding || encoding === 'utf8') {
return normalized;
}
return Buffer.from(normalized, 'utf8');
};
this.link = async (existingPath, newPath) => {
const existingPathStr = typeof existingPath === 'string' ? existingPath : existingPath.toString();
const newPathStr = typeof newPath === 'string' ? newPath : newPath.toString();
const existingParts = this.parsePath(existingPathStr);
const newParts = this.parsePath(newPathStr);
if (newParts.length === 0) {
throw new Error('Cannot create link at root');
}
const operations = this.navigateToPath(existingParts);
operations.push(builder_1.nfs.SAVEFH());
operations.push(builder_1.nfs.PUTROOTFH());
for (const part of newParts.slice(0, -1)) {
operations.push(builder_1.nfs.LOOKUP(part));
}
const newname = newParts[newParts.length - 1];
operations.push(builder_1.nfs.LINK(newname));
const response = await this.fs.compound(operations);
if (response.status !== 0) {
throw new Error(`Failed to create link: ${response.status}`);
}
const linkRes = response.resarray[response.resarray.length - 1];
if (linkRes.status !== 0) {
throw new Error(`Failed to create link: ${linkRes.status}`);
}
};
this.symlink = async (target, path, type) => {
const targetStr = typeof target === 'string' ? target : target.toString();
const pathStr = typeof path === 'string' ? path : path.toString();
const parts = this.parsePath(pathStr);
if (parts.length === 0) {
throw new Error('Cannot create symlink at root');
}
const operations = this.navigateToParent(parts);
const linkname = parts[parts.length - 1];
const createType = new structs.Nfsv4CreateType(5, new structs.Nfsv4CreateTypeLink(targetStr));
const emptyAttrs = builder_1.nfs.Fattr([], new Uint8Array(0));
operations.push(builder_1.nfs.CREATE(createType, linkname, emptyAttrs));
const response = await this.fs.compound(operations);
if (response.status !== 0) {
throw new Error(`Failed to create symlink: ${response.status}`);
}
const createRes = response.resarray[response.resarray.length - 1];
if (createRes.status !== 0) {
throw new Error(`Failed to create symlink: ${createRes.status}`);
}
};
this.utimes = async (path, atime, mtime) => {
const pathStr = typeof path === 'string' ? path : path.toString();
const parts = this.parsePath(pathStr);
const operations = this.navigateToPath(parts);
const atimeMs = typeof atime === 'number' ? atime : atime instanceof Date ? atime.getTime() : Date.now();
const mtimeMs = typeof mtime === 'number' ? mtime : mtime instanceof Date ? mtime.getTime() : Date.now();
const writer = new Writer_1.Writer(64);
const xdr = new XdrEncoder_1.XdrEncoder(writer);
xdr.writeUnsignedInt(1);
xdr.writeHyper(BigInt(Math.floor(atimeMs / 1000)));
xdr.writeUnsignedInt((atimeMs % 1000) * 1000000);
xdr.writeUnsignedInt(1);
xdr.writeHyper(BigInt(Math.floor(mtimeMs / 1000)));
xdr.writeUnsignedInt((mtimeMs % 1000) * 1000000);
const attrVals = writer.flush();
const timeAttrs = builder_1.nfs.Fattr([48, 54], attrVals);
const stateid = builder_1.nfs.Stateid(0, new Uint8Array(12));
operations.push(builder_1.nfs.SETATTR(stateid, timeAttrs));
const response = await this.fs.compound(operations);
if (response.status !== 0) {
throw new Error(`Failed to set times: ${response.status}`);
}
const setattrRes = response.resarray[response.resarray.length - 1];
if (setattrRes.status !== 0) {
throw new Error(`Failed to set times: ${setattrRes.status}`);
}
};
this.readlink = async (path, options) => {
const encoding = typeof options === 'string' ? options : options?.encoding;
const pathStr = typeof path === 'string' ? path : path.toString();
const parts = this.parsePath(pathStr);
const operations = this.navigateToPath(parts);
operations.push(builder_1.nfs.READLINK());
const response = await this.fs.compound(operations);
if (response.status !== 0) {
throw new Error(`Failed to read link: ${response.status}`);
}
const readlinkRes = response.resarray[response.resarray.length - 1];
if (readlinkRes.status !== 0 || !readlinkRes.resok) {
throw new Error(`Failed to read link: ${readlinkRes.status}`);
}
if (!encoding || encoding === 'utf8') {
return readlinkRes.resok.link;
}
return Buffer.from(readlinkRes.resok.link, 'utf8');
};
this.opendir = async (path, options) => {
const pathStr = typeof path === 'string' ? path : path.toString();
const parts = this.parsePath(pathStr);
const operations = this.navigateToPath(parts);
return new NfsFsDir_1.NfsFsDir(pathStr, this.fs, operations);
};
this.mkdtemp = async (prefix, options) => {
const encoding = typeof options === 'string' ? options : options?.encoding;
const randomSuffix = Math.random().toString(36).substring(2, 8);
const dirName = prefix + randomSuffix;
await this.mkdir(dirName);
if (!encoding || encoding === 'utf8')
return dirName;
return Buffer.from(dirName, 'utf8');
};
this.chmod = async (path, mode) => {
const pathStr = typeof path === 'string' ? path : path.toString();
const parts = this.parsePath(pathStr);
const operations = this.navigateToPath(parts);
const modeValue = typeof mode === 'number' ? mode : parseInt(mode.toString(), 8);
const writer = new Writer_1.Writer(8);
const xdr = new XdrEncoder_1.XdrEncoder(writer);
xdr.writeUnsignedInt(modeValue);
const attrVals = writer.flush();
const attrs = builder_1.nfs.Fattr([33], attrVals);
const stateid = builder_1.nfs.Stateid(0, new Uint8Array(12));
operations.push(builder_1.nfs.SETATTR(stateid, attrs));
const response = await this.fs.compound(operations);
if (response.status !== 0) {
throw new Error(`Failed to chmod: ${response.status}`);
}
const setattrRes = response.resarray[response.resarray.length - 1];
if (setattrRes.status !== 0) {
throw new Error(`Failed to chmod: ${setattrRes.status}`);
}
};
this.chown = async (path, uid, gid) => {
const pathStr = typeof path === 'string' ? path : path.toString();
const parts = this.parsePath(pathStr);
const operations = this.navigateToPath(parts);
const writer = new Writer_1.Writer(64);
const xdr = new XdrEncoder_1.XdrEncoder(writer);
xdr.writeStr(uid.toString());
xdr.writeStr(gid.toString());
const attrVals = writer.flush();
const attrs = builder_1.nfs.Fattr([36, 37], attrVals);
const stateid = builder_1.nfs.Stateid(0, new Uint8Array(12));
operations.push(builder_1.nfs.SETATTR(stateid, attrs));
const response = await this.fs.compound(operations);
if (response.status !== 0) {
throw new Error(`Failed to chown: ${response.status}`);
}
const setattrRes = response.resarray[response.resarray.length - 1];
if (setattrRes.status !== 0) {
throw new Error(`Failed to chown: ${setattrRes.status}`);
}
};
this.lchmod = async (path, mode) => {
return this.chmod(path, mode);
};
this.lchown = async (path, uid, gid) => {
return this.chown(path, uid, gid);
};
this.lutimes = async (path, atime, mtime) => {
return this.utimes(path, atime, mtime);
};
this.open = async (path, flags, mode) => {
const pathStr = typeof path === 'string' ? path : path.toString();
const parts = this.parsePath(pathStr);
const operations = this.navigateToParent(parts);
const filename = parts[parts.length - 1];
const openOwner = this.createDefaultOpenOwner();
const claim = builder_1.nfs.OpenClaimNull(filename);
let access = 1;
const openSeqid = this.nextOpenOwnerSeqid(openOwner);
if (typeof flags === 'string') {
if (flags.includes('r') && flags.includes('+')) {
access = 3;
}
else if (flags.includes('w') || flags.includes('a')) {
access = 2;
if (flags.includes('+')) {
access = 3;
}
}
}
else if (typeof flags === 'number') {
const O_RDONLY = 0;
const O_WRONLY = 1;
const O_RDWR = 2;
const O_ACCMODE = 3;
const accessMode = flags & O_ACCMODE;
switch (accessMode) {
case O_RDONLY:
access = 1;
break;
case O_WRONLY:
access = 2;
break;
case O_RDWR:
access = 3;
break;
}
}
operations.push(builder_1.nfs.OPEN(openSeqid, access, 0, openOwner, builder_1.nfs.OpenHowNoCreate(), claim));
const openResponse = await this.fs.compound(operations);
if (openResponse.status !== 0) {
throw new Error(`Failed to open file: ${openResponse.status}`);
}
const openRes = openResponse.resarray[openResponse.resarray.length - 1];
if (openRes.status !== 0 || !openRes.resok) {
throw new Error(`Failed to open file: ${openRes.status}`);
}
const stateid = openRes.resok.stateid;
const fd = Math.floor(Math.random() * 1000000);
return new NfsFsFileHandle_1.NfsFsFileHandle(fd, pathStr, this, stateid, openOwner);
};
this.statfs = (path, options) => {
throw new Error('Not implemented.');
};
this.watch = (filename, options) => {
throw new Error('Not implemented.');
};
this.glob = (pattern, options) => {
throw new Error('Not implemented.');
};
}
makeOpenOwnerKey(owner) {
return `${owner.clientid}:${Buffer.from(owner.owner).toString('hex')}`;
}
nextOpenOwnerSeqid(owner) {
const key = this.makeOpenOwnerKey(owner);
const last = this.openOwnerSeqids.get(key);
const next = last === undefined ? 0 : last === 0xffffffff ? 1 : (last + 1) >>> 0;
this.openOwnerSeqids.set(key, next);
return next;
}
createDefaultOpenOwner() {
return builder_1.nfs.OpenOwner(BigInt(1), new Uint8Array(this.defaultOpenOwnerId));
}
attrNumsToBitmap(attrNums) {
const bitmap = [];
for (const attrNum of attrNums) {
const wordIndex = Math.floor(attrNum / 32);
const bitIndex = attrNum % 32;
while (bitmap.length <= wordIndex) {
bitmap.push(0);
}
bitmap[wordIndex] |= 1 << bitIndex;
}
return bitmap;
}
parsePath(path) {
const normalized = path.replace(/^\/+/, '').replace(/\/+$/, '');
if (!normalized)
return [];
return normalized.split('/').filter((part) => part.length > 0);
}
navigateToParent(parts) {
const operations = [builder_1.nfs.PUTROOTFH()];
for (const part of parts.slice(0, -1)) {
operations.push(builder_1.nfs.LOOKUP(part));
}
return operations;
}
navigateToPath(parts) {
const operations = [builder_1.nfs.PUTROOTFH()];
for (const part of parts) {
operations.push(builder_1.nfs.LOOKUP(part));
}
return operations;
}
encodeData(data) {
if (data instanceof Uint8Array)
return data;
if (data instanceof ArrayBuffer)
return new Uint8Array(data);
if (typeof data === 'string')
return new TextEncoder().encode(data);
if (Buffer.isBuffer(data))
return new Uint8Array(data);
throw new Error('Unsupported data type');
}
decodeData(data, encoding) {
if (!encoding || encoding === 'buffer')
return Buffer.from(data);
return new TextDecoder(encoding).decode(data);
}
}
exports.Nfsv4FsClient = Nfsv4FsClient;
//# sourceMappingURL=Nfsv4FsClient.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,41 @@
/// <reference types="node" />
import * as stream from 'node:stream';
import { Nfsv4CompoundRequest, Nfsv4CompoundResponse, Nfsv4Request } from '../messages';
import type { Nfsv4Client } from './types';
export interface Nfsv4TcpClientOpts {
host?: string;
port?: number;
timeout?: number;
debug?: boolean;
logger?: Pick<typeof console, 'log' | 'error'>;
}
export declare class Nfsv4TcpClient implements Nfsv4Client {
static fromDuplex(duplex: stream.Duplex, opts?: Nfsv4TcpClientOpts): Nfsv4TcpClient;
readonly host: string;
readonly port: number;
readonly timeout: number;
debug: boolean;
logger: Pick<typeof console, 'log' | 'error'>;
private socket;
private connected;
private connecting;
private xid;
private seqid;
private pendingRequests;
private readonly rmDecoder;
private readonly rpcDecoder;
private readonly nfsDecoder;
private readonly nfsEncoder;
constructor(opts?: Nfsv4TcpClientOpts);
private nextXid;
connect(): Promise<void>;
protected setSocket(socket: stream.Duplex): void;
private onData;
private onRpcMessage;
private onClose;
compound(request: Nfsv4CompoundRequest): Promise<Nfsv4CompoundResponse>;
compound(operations: Nfsv4Request[], tag?: string, minorversion?: number): Promise<Nfsv4CompoundResponse>;
null(): Promise<void>;
close(): void;
isConnected(): boolean;
}
+216
View File
@@ -0,0 +1,216 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Nfsv4TcpClient = void 0;
const tslib_1 = require("tslib");
const net = tslib_1.__importStar(require("node:net"));
const Nfsv4Decoder_1 = require("../Nfsv4Decoder");
const Nfsv4FullEncoder_1 = require("../Nfsv4FullEncoder");
const rm_1 = require("../../../rm");
const rpc_1 = require("../../../rpc");
const constants_1 = require("../constants");
const messages_1 = require("../messages");
class Nfsv4TcpClient {
static fromDuplex(duplex, opts = {}) {
const client = new Nfsv4TcpClient(opts);
client.setSocket(duplex);
return client;
}
constructor(opts = {}) {
this.socket = null;
this.connected = false;
this.connecting = false;
this.xid = 0;
this.seqid = 0;
this.pendingRequests = new Map();
this.host = opts.host || '127.0.0.1';
this.port = opts.port || 2049;
this.timeout = opts.timeout || 30000;
this.debug = !!opts.debug;
this.logger = opts.logger || console;
this.rmDecoder = new rm_1.RmRecordDecoder();
this.rpcDecoder = new rpc_1.RpcMessageDecoder();
this.nfsDecoder = new Nfsv4Decoder_1.Nfsv4Decoder();
this.nfsEncoder = new Nfsv4FullEncoder_1.Nfsv4FullEncoder();
}
nextXid() {
this.xid = (this.xid + 1) >>> 0;
if (this.xid === 0)
this.xid = 1;
return this.xid;
}
async connect() {
if (this.connected)
return;
if (this.connecting)
throw new Error('Connection already in progress');
return new Promise((resolve, reject) => {
this.connecting = true;
const onError = (err) => {
this.connecting = false;
this.connected = false;
if (this.debug)
this.logger.error('Socket error:', err);
reject(err);
};
const socket = net.connect({ host: this.host, port: this.port }, () => {
if (this.debug)
this.logger.log(`Connected to NFSv4 server at ${this.host}:${this.port}`);
socket.removeListener('error', onError);
resolve();
this.setSocket(socket);
});
socket.once('error', onError);
});
}
setSocket(socket) {
socket.on('data', this.onData.bind(this));
socket.on('close', this.onClose.bind(this));
socket.on('error', (err) => {
this.connecting = false;
this.connected = false;
if (this.debug)
this.logger.error('Socket error:', err);
});
this.connected = true;
this.connecting = false;
this.socket = socket;
}
onData(data) {
const { rmDecoder, rpcDecoder } = this;
rmDecoder.push(data);
let record = rmDecoder.readRecord();
while (record) {
if (record.size()) {
const rpcMessage = rpcDecoder.decodeMessage(record);
if (rpcMessage)
this.onRpcMessage(rpcMessage);
else if (this.debug)
this.logger.error('Failed to decode RPC message');
}
record = rmDecoder.readRecord();
}
}
onRpcMessage(msg) {
if (msg instanceof rpc_1.RpcAcceptedReplyMessage) {
const pending = this.pendingRequests.get(msg.xid);
if (!pending) {
if (this.debug)
this.logger.error(`No pending request for XID ${msg.xid}`);
return;
}
this.pendingRequests.delete(msg.xid);
if (pending.timeout)
clearTimeout(pending.timeout);
if (msg.stat !== 0) {
pending.reject(new Error(`RPC accepted reply error: stat=${msg.stat}`));
return;
}
if (!msg.results) {
if (pending.resolve.length === 0) {
pending.resolve();
return;
}
pending.reject(new Error('No results in accepted reply'));
return;
}
const response = this.nfsDecoder.decodeCompoundResponse(msg.results);
if (!response) {
pending.reject(new Error('Failed to decode COMPOUND response'));
return;
}
pending.resolve(response);
}
else if (msg instanceof rpc_1.RpcRejectedReplyMessage) {
const pending = this.pendingRequests.get(msg.xid);
if (!pending) {
if (this.debug)
this.logger.error(`No pending request for XID ${msg.xid}`);
return;
}
this.pendingRequests.delete(msg.xid);
if (pending.timeout)
clearTimeout(pending.timeout);
pending.reject(new Error(`RPC rejected reply: stat=${msg.stat}`));
}
else {
if (this.debug)
this.logger.error('Unexpected RPC message type:', msg);
}
}
onClose() {
this.connected = false;
this.connecting = false;
if (this.debug)
this.logger.log('Connection closed');
const error = new Error('Connection closed');
this.pendingRequests.forEach((pending, xid) => {
if (pending.timeout)
clearTimeout(pending.timeout);
pending.reject(error);
});
this.pendingRequests.clear();
}
async compound(requestOrOps, tag = '', minorversion = 0) {
if (!this.connected)
throw new Error('Not connected');
const request = requestOrOps instanceof messages_1.Nfsv4CompoundRequest
? requestOrOps
: new messages_1.Nfsv4CompoundRequest(tag, minorversion, requestOrOps);
const xid = this.nextXid();
const cred = new rpc_1.RpcOpaqueAuth(0, constants_1.EMPTY_READER);
const verf = new rpc_1.RpcOpaqueAuth(0, constants_1.EMPTY_READER);
const encoded = this.nfsEncoder.encodeCall(xid, 1, cred, verf, request);
return new Promise((resolve, reject) => {
const timeout = setTimeout(() => {
this.pendingRequests.delete(xid);
reject(new Error(`Request timeout (XID ${xid})`));
}, this.timeout);
this.pendingRequests.set(xid, { resolve, reject, timeout });
this.socket.write(encoded);
if (this.debug) {
this.logger.log(`Sent COMPOUND request (XID ${xid}): ${request.argarray.length} operations`);
}
});
}
async null() {
if (!this.connected)
throw new Error('Not connected');
const xid = this.nextXid();
const cred = new rpc_1.RpcOpaqueAuth(0, constants_1.EMPTY_READER);
const verf = new rpc_1.RpcOpaqueAuth(0, constants_1.EMPTY_READER);
const writer = this.nfsEncoder.writer;
const rmEncoder = this.nfsEncoder.rmEncoder;
const rpcEncoder = this.nfsEncoder.rpcEncoder;
const state = rmEncoder.startRecord();
rpcEncoder.writeCall(xid, 100003, 4, 0, cred, verf);
rmEncoder.endRecord(state);
const encoded = writer.flush();
return new Promise((resolve, reject) => {
const timeout = setTimeout(() => {
this.pendingRequests.delete(xid);
reject(new Error(`NULL request timeout (XID ${xid})`));
}, this.timeout);
this.pendingRequests.set(xid, {
resolve: () => resolve(),
reject,
timeout,
});
this.socket.write(encoded);
if (this.debug)
this.logger.log(`Sent NULL request (XID ${xid})`);
});
}
close() {
if (this.socket) {
this.socket.end();
this.socket = null;
}
this.connected = false;
this.connecting = false;
}
isConnected() {
return this.connected;
}
}
exports.Nfsv4TcpClient = Nfsv4TcpClient;
//# sourceMappingURL=Nfsv4TcpClient.js.map
File diff suppressed because one or more lines are too long
+9
View File
@@ -0,0 +1,9 @@
import type { FsPromisesApi } from 'memfs/lib/node/types';
import * as msg from '../messages';
export interface Nfsv4Client {
compound(request: msg.Nfsv4CompoundRequest): Promise<msg.Nfsv4CompoundResponse>;
compound(operations: msg.Nfsv4Request[], tag?: string, minorversion?: number): Promise<msg.Nfsv4CompoundResponse>;
null(): Promise<void>;
}
export interface NfsFsClient extends Pick<FsPromisesApi, 'readFile' | 'writeFile' | 'readdir' | 'mkdir' | 'access' | 'appendFile' | 'copyFile' | 'link' | 'realpath' | 'rename' | 'rmdir' | 'truncate' | 'unlink' | 'utimes' | 'symlink' | 'stat' | 'readlink' | 'opendir' | 'open' | 'chmod' | 'rm' | 'chown' | 'lchmod' | 'lchown' | 'lutimes' | 'lstat' | 'mkdtemp' | 'statfs' | 'watch' | 'glob'> {
}
+3
View File
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=types.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/nfs/v4/client/types.ts"],"names":[],"mappings":""}
+316
View File
@@ -0,0 +1,316 @@
import { Reader } from '@jsonjoy.com/buffers/lib/Reader';
export declare const EMPY_U8: Uint8Array;
export declare const EMPTY_READER: Reader;
export declare const enum Nfsv4Const {
PROGRAM = 100003,
VERSION = 4,
FHSIZE = 128,
VERIFIER_SIZE = 8,
OPAQUE_LIMIT = 1024,
OTHER_SIZE = 12
}
export declare const enum Nfsv4Proc {
NULL = 0,
COMPOUND = 1
}
export declare const enum Nfsv4CbProc {
CB_NULL = 0,
CB_COMPOUND = 1
}
export declare const enum Nfsv4Op {
ACCESS = 3,
CLOSE = 4,
COMMIT = 5,
CREATE = 6,
DELEGPURGE = 7,
DELEGRETURN = 8,
GETATTR = 9,
GETFH = 10,
LINK = 11,
LOCK = 12,
LOCKT = 13,
LOCKU = 14,
LOOKUP = 15,
LOOKUPP = 16,
NVERIFY = 17,
OPEN = 18,
OPENATTR = 19,
OPEN_CONFIRM = 20,
OPEN_DOWNGRADE = 21,
PUTFH = 22,
PUTPUBFH = 23,
PUTROOTFH = 24,
READ = 25,
READDIR = 26,
READLINK = 27,
REMOVE = 28,
RENAME = 29,
RENEW = 30,
RESTOREFH = 31,
SAVEFH = 32,
SECINFO = 33,
SETATTR = 34,
SETCLIENTID = 35,
SETCLIENTID_CONFIRM = 36,
VERIFY = 37,
WRITE = 38,
RELEASE_LOCKOWNER = 39,
ILLEGAL = 10044
}
export declare const enum Nfsv4CbOp {
CB_GETATTR = 3,
CB_RECALL = 4,
CB_ILLEGAL = 10044
}
export declare const enum Nfsv4Stat {
NFS4_OK = 0,
NFS4ERR_PERM = 1,
NFS4ERR_NOENT = 2,
NFS4ERR_IO = 5,
NFS4ERR_NXIO = 6,
NFS4ERR_ACCESS = 13,
NFS4ERR_EXIST = 17,
NFS4ERR_XDEV = 18,
NFS4ERR_NOTDIR = 20,
NFS4ERR_ISDIR = 21,
NFS4ERR_INVAL = 22,
NFS4ERR_FBIG = 27,
NFS4ERR_NOSPC = 28,
NFS4ERR_ROFS = 30,
NFS4ERR_MLINK = 31,
NFS4ERR_NAMETOOLONG = 63,
NFS4ERR_NOTEMPTY = 66,
NFS4ERR_DQUOT = 69,
NFS4ERR_STALE = 70,
NFS4ERR_BADHANDLE = 10001,
NFS4ERR_BAD_COOKIE = 10003,
NFS4ERR_NOTSUPP = 10004,
NFS4ERR_TOOSMALL = 10005,
NFS4ERR_SERVERFAULT = 10006,
NFS4ERR_BADTYPE = 10007,
NFS4ERR_DELAY = 10008,
NFS4ERR_SAME = 10009,
NFS4ERR_DENIED = 10010,
NFS4ERR_EXPIRED = 10011,
NFS4ERR_LOCKED = 10012,
NFS4ERR_GRACE = 10013,
NFS4ERR_FHEXPIRED = 10014,
NFS4ERR_SHARE_DENIED = 10015,
NFS4ERR_WRONGSEC = 10016,
NFS4ERR_CLID_INUSE = 10017,
NFS4ERR_RESOURCE = 10018,
NFS4ERR_MOVED = 10019,
NFS4ERR_NOFILEHANDLE = 10020,
NFS4ERR_MINOR_VERS_MISMATCH = 10021,
NFS4ERR_STALE_CLIENTID = 10022,
NFS4ERR_STALE_STATEID = 10023,
NFS4ERR_OLD_STATEID = 10024,
NFS4ERR_BAD_STATEID = 10025,
NFS4ERR_BAD_SEQID = 10026,
NFS4ERR_NOT_SAME = 10027,
NFS4ERR_LOCK_RANGE = 10028,
NFS4ERR_SYMLINK = 10029,
NFS4ERR_RESTOREFH = 10030,
NFS4ERR_LEASE_MOVED = 10031,
NFS4ERR_ATTRNOTSUPP = 10032,
NFS4ERR_NO_GRACE = 10033,
NFS4ERR_RECLAIM_BAD = 10034,
NFS4ERR_RECLAIM_CONFLICT = 10035,
NFS4ERR_BADXDR = 10036,
NFS4ERR_LOCKS_HELD = 10037,
NFS4ERR_OPENMODE = 10038,
NFS4ERR_BADOWNER = 10039,
NFS4ERR_BADCHAR = 10040,
NFS4ERR_BADNAME = 10041,
NFS4ERR_BAD_RANGE = 10042,
NFS4ERR_LOCK_NOTSUPP = 10043,
NFS4ERR_OP_ILLEGAL = 10044,
NFS4ERR_DEADLOCK = 10045,
NFS4ERR_FILE_OPEN = 10046,
NFS4ERR_ADMIN_REVOKED = 10047,
NFS4ERR_CB_PATH_DOWN = 10048
}
export declare const enum Nfsv4FType {
NF4REG = 1,
NF4DIR = 2,
NF4BLK = 3,
NF4CHR = 4,
NF4LNK = 5,
NF4SOCK = 6,
NF4FIFO = 7,
NF4ATTRDIR = 8,
NF4NAMEDATTR = 9
}
export declare const enum Nfsv4TimeHow {
SET_TO_SERVER_TIME4 = 0,
SET_TO_CLIENT_TIME4 = 1
}
export declare const enum Nfsv4StableHow {
UNSTABLE4 = 0,
DATA_SYNC4 = 1,
FILE_SYNC4 = 2
}
export declare const enum Nfsv4CreateMode {
UNCHECKED4 = 0,
GUARDED4 = 1,
EXCLUSIVE4 = 2
}
export declare const enum Nfsv4OpenFlags {
OPEN4_NOCREATE = 0,
OPEN4_CREATE = 1
}
export declare const enum Nfsv4OpenAccess {
OPEN4_SHARE_ACCESS_READ = 1,
OPEN4_SHARE_ACCESS_WRITE = 2,
OPEN4_SHARE_ACCESS_BOTH = 3
}
export declare const enum Nfsv4OpenDeny {
OPEN4_SHARE_DENY_NONE = 0,
OPEN4_SHARE_DENY_READ = 1,
OPEN4_SHARE_DENY_WRITE = 2,
OPEN4_SHARE_DENY_BOTH = 3
}
export declare const enum Nfsv4OpenClaimType {
CLAIM_NULL = 0,
CLAIM_PREVIOUS = 1,
CLAIM_DELEGATE_CUR = 2,
CLAIM_DELEGATE_PREV = 3
}
export declare const enum Nfsv4DelegType {
OPEN_DELEGATE_NONE = 0,
OPEN_DELEGATE_READ = 1,
OPEN_DELEGATE_WRITE = 2
}
export declare const enum Nfsv4LockType {
READ_LT = 1,
WRITE_LT = 2,
READW_LT = 3,
WRITEW_LT = 4
}
export declare const enum Nfsv4Access {
ACCESS4_READ = 1,
ACCESS4_LOOKUP = 2,
ACCESS4_MODIFY = 4,
ACCESS4_EXTEND = 8,
ACCESS4_DELETE = 16,
ACCESS4_EXECUTE = 32
}
export declare const enum Nfsv4AceType {
ACE4_ACCESS_ALLOWED_ACE_TYPE = 0,
ACE4_ACCESS_DENIED_ACE_TYPE = 1,
ACE4_SYSTEM_AUDIT_ACE_TYPE = 2,
ACE4_SYSTEM_ALARM_ACE_TYPE = 3
}
export declare const enum Nfsv4AceFlag {
ACE4_FILE_INHERIT_ACE = 1,
ACE4_DIRECTORY_INHERIT_ACE = 2,
ACE4_NO_PROPAGATE_INHERIT_ACE = 4,
ACE4_INHERIT_ONLY_ACE = 8,
ACE4_SUCCESSFUL_ACCESS_ACE_FLAG = 16,
ACE4_FAILED_ACCESS_ACE_FLAG = 32,
ACE4_IDENTIFIER_GROUP = 64
}
export declare const enum Nfsv4AceMask {
ACE4_READ_DATA = 1,
ACE4_LIST_DIRECTORY = 1,
ACE4_WRITE_DATA = 2,
ACE4_ADD_FILE = 2,
ACE4_APPEND_DATA = 4,
ACE4_ADD_SUBDIRECTORY = 4,
ACE4_READ_NAMED_ATTRS = 8,
ACE4_WRITE_NAMED_ATTRS = 16,
ACE4_EXECUTE = 32,
ACE4_DELETE_CHILD = 64,
ACE4_READ_ATTRIBUTES = 128,
ACE4_WRITE_ATTRIBUTES = 256,
ACE4_DELETE = 65536,
ACE4_READ_ACL = 131072,
ACE4_WRITE_ACL = 262144,
ACE4_WRITE_OWNER = 524288,
ACE4_SYNCHRONIZE = 1048576
}
export declare const enum Nfsv4AclSupport {
ACL4_SUPPORT_ALLOW_ACL = 1,
ACL4_SUPPORT_DENY_ACL = 2,
ACL4_SUPPORT_AUDIT_ACL = 4,
ACL4_SUPPORT_ALARM_ACL = 8
}
export declare const enum Nfsv4Mode {
MODE4_SUID = 2048,
MODE4_SGID = 1024,
MODE4_SVTX = 512,
MODE4_RUSR = 256,
MODE4_WUSR = 128,
MODE4_XUSR = 64,
MODE4_RGRP = 32,
MODE4_WGRP = 16,
MODE4_XGRP = 8,
MODE4_ROTH = 4,
MODE4_WOTH = 2,
MODE4_XOTH = 1
}
export declare const enum Nfsv4FhExpireType {
FH4_PERSISTENT = 0,
FH4_NOEXPIRE_WITH_OPEN = 1,
FH4_VOLATILE_ANY = 2,
FH4_VOL_MIGRATION = 4,
FH4_VOL_RENAME = 8
}
export declare const enum Nfsv4Attr {
FATTR4_SUPPORTED_ATTRS = 0,
FATTR4_TYPE = 1,
FATTR4_FH_EXPIRE_TYPE = 2,
FATTR4_CHANGE = 3,
FATTR4_SIZE = 4,
FATTR4_LINK_SUPPORT = 5,
FATTR4_SYMLINK_SUPPORT = 6,
FATTR4_NAMED_ATTR = 7,
FATTR4_FSID = 8,
FATTR4_UNIQUE_HANDLES = 9,
FATTR4_LEASE_TIME = 10,
FATTR4_RDATTR_ERROR = 11,
FATTR4_ACL = 12,
FATTR4_ACLSUPPORT = 13,
FATTR4_ARCHIVE = 14,
FATTR4_CANSETTIME = 15,
FATTR4_CASE_INSENSITIVE = 16,
FATTR4_CASE_PRESERVING = 17,
FATTR4_CHOWN_RESTRICTED = 18,
FATTR4_FILEHANDLE = 19,
FATTR4_FILEID = 20,
FATTR4_FILES_AVAIL = 21,
FATTR4_FILES_FREE = 22,
FATTR4_FILES_TOTAL = 23,
FATTR4_FS_LOCATIONS = 24,
FATTR4_HIDDEN = 25,
FATTR4_HOMOGENEOUS = 26,
FATTR4_MAXFILESIZE = 27,
FATTR4_MAXLINK = 28,
FATTR4_MAXNAME = 29,
FATTR4_MAXREAD = 30,
FATTR4_MAXWRITE = 31,
FATTR4_MIMETYPE = 32,
FATTR4_MODE = 33,
FATTR4_NO_TRUNC = 34,
FATTR4_NUMLINKS = 35,
FATTR4_OWNER = 36,
FATTR4_OWNER_GROUP = 37,
FATTR4_QUOTA_AVAIL_HARD = 38,
FATTR4_QUOTA_AVAIL_SOFT = 39,
FATTR4_QUOTA_USED = 40,
FATTR4_RAWDEV = 41,
FATTR4_SPACE_AVAIL = 42,
FATTR4_SPACE_FREE = 43,
FATTR4_SPACE_TOTAL = 44,
FATTR4_SPACE_USED = 45,
FATTR4_SYSTEM = 46,
FATTR4_TIME_ACCESS = 47,
FATTR4_TIME_ACCESS_SET = 48,
FATTR4_TIME_BACKUP = 49,
FATTR4_TIME_CREATE = 50,
FATTR4_TIME_DELTA = 51,
FATTR4_TIME_METADATA = 52,
FATTR4_TIME_MODIFY = 53,
FATTR4_TIME_MODIFY_SET = 54,
FATTR4_MOUNTED_ON_FILEID = 55
}
+7
View File
@@ -0,0 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EMPTY_READER = exports.EMPY_U8 = void 0;
const Reader_1 = require("@jsonjoy.com/buffers/lib/Reader");
exports.EMPY_U8 = new Uint8Array(0);
exports.EMPTY_READER = new Reader_1.Reader(exports.EMPY_U8);
//# sourceMappingURL=constants.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/nfs/v4/constants.ts"],"names":[],"mappings":";;;AAAA,4DAAuD;AAE1C,QAAA,OAAO,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;AAC5B,QAAA,YAAY,GAAG,IAAI,eAAM,CAAC,eAAO,CAAC,CAAC"}
+6
View File
@@ -0,0 +1,6 @@
export declare class Nfsv4DecodingError extends Error {
constructor(message?: string);
}
export declare class Nfsv4EncodingError extends Error {
constructor(message?: string);
}
+16
View File
@@ -0,0 +1,16 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Nfsv4EncodingError = exports.Nfsv4DecodingError = void 0;
class Nfsv4DecodingError extends Error {
constructor(message) {
super(message ? 'NFSv4_DECODING: ' + message : 'NFSv4_DECODING');
}
}
exports.Nfsv4DecodingError = Nfsv4DecodingError;
class Nfsv4EncodingError extends Error {
constructor(message) {
super(message ? 'NFSv4_ENCODING: ' + message : 'NFSv4_ENCODING');
}
}
exports.Nfsv4EncodingError = Nfsv4EncodingError;
//# sourceMappingURL=errors.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/nfs/v4/errors.ts"],"names":[],"mappings":";;;AAAA,MAAa,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,OAAgB;QAC1B,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB,GAAG,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;IACnE,CAAC;CACF;AAJD,gDAIC;AAED,MAAa,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,OAAgB;QAC1B,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB,GAAG,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;IACnE,CAAC;CACF;AAJD,gDAIC"}
+23
View File
@@ -0,0 +1,23 @@
import * as constants from './constants';
import * as structs from './structs';
import * as msg from './messages';
export declare const formatNfsv4Stat: (stat: constants.Nfsv4Stat) => string;
export declare const formatNfsv4Op: (op: constants.Nfsv4Op) => string;
export declare const formatNfsv4Attr: (attr: constants.Nfsv4Attr) => string;
export declare const formatNfsv4FType: (ftype: constants.Nfsv4FType) => string;
export declare const formatNfsv4TimeHow: (how: constants.Nfsv4TimeHow) => string;
export declare const formatNfsv4StableHow: (stable: constants.Nfsv4StableHow) => string;
export declare const formatNfsv4CreateMode: (mode: constants.Nfsv4CreateMode) => string;
export declare const formatNfsv4OpenFlags: (flags: constants.Nfsv4OpenFlags) => string;
export declare const formatNfsv4OpenAccess: (access: constants.Nfsv4OpenAccess) => string;
export declare const formatNfsv4OpenDeny: (deny: constants.Nfsv4OpenDeny) => string;
export declare const formatNfsv4OpenClaimType: (claim: constants.Nfsv4OpenClaimType) => string;
export declare const formatNfsv4DelegType: (deleg: constants.Nfsv4DelegType) => string;
export declare const formatNfsv4LockType: (locktype: constants.Nfsv4LockType) => string;
export declare const formatNfsv4Access: (access: number) => string;
export declare const formatNfsv4Mode: (mode: number) => string;
export declare const formatNfsv4Bitmap: (bitmap: structs.Nfsv4Bitmap) => string;
export declare const formatNfsv4Request: (req: msg.Nfsv4Request, tab?: string) => string;
export declare const formatNfsv4Response: (res: msg.Nfsv4Response, tab?: string) => string;
export declare const formatNfsv4CompoundRequest: (req: msg.Nfsv4CompoundRequest, tab?: string) => string;
export declare const formatNfsv4CompoundResponse: (res: msg.Nfsv4CompoundResponse, tab?: string) => string;
+870
View File
@@ -0,0 +1,870 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.formatNfsv4CompoundResponse = exports.formatNfsv4CompoundRequest = exports.formatNfsv4Response = exports.formatNfsv4Request = exports.formatNfsv4Bitmap = exports.formatNfsv4Mode = exports.formatNfsv4Access = exports.formatNfsv4LockType = exports.formatNfsv4DelegType = exports.formatNfsv4OpenClaimType = exports.formatNfsv4OpenDeny = exports.formatNfsv4OpenAccess = exports.formatNfsv4OpenFlags = exports.formatNfsv4CreateMode = exports.formatNfsv4StableHow = exports.formatNfsv4TimeHow = exports.formatNfsv4FType = exports.formatNfsv4Attr = exports.formatNfsv4Op = exports.formatNfsv4Stat = void 0;
const tslib_1 = require("tslib");
const msg = tslib_1.__importStar(require("./messages"));
const attributes_1 = require("./attributes");
const printTree_1 = require("tree-dump/lib/printTree");
const formatNfsv4Stat = (stat) => {
switch (stat) {
case 0:
return 'NFS4_OK';
case 1:
return 'NFS4ERR_PERM';
case 2:
return 'NFS4ERR_NOENT';
case 5:
return 'NFS4ERR_IO';
case 6:
return 'NFS4ERR_NXIO';
case 13:
return 'NFS4ERR_ACCESS';
case 17:
return 'NFS4ERR_EXIST';
case 18:
return 'NFS4ERR_XDEV';
case 20:
return 'NFS4ERR_NOTDIR';
case 21:
return 'NFS4ERR_ISDIR';
case 22:
return 'NFS4ERR_INVAL';
case 27:
return 'NFS4ERR_FBIG';
case 28:
return 'NFS4ERR_NOSPC';
case 30:
return 'NFS4ERR_ROFS';
case 31:
return 'NFS4ERR_MLINK';
case 63:
return 'NFS4ERR_NAMETOOLONG';
case 66:
return 'NFS4ERR_NOTEMPTY';
case 69:
return 'NFS4ERR_DQUOT';
case 70:
return 'NFS4ERR_STALE';
case 10001:
return 'NFS4ERR_BADHANDLE';
case 10003:
return 'NFS4ERR_BAD_COOKIE';
case 10004:
return 'NFS4ERR_NOTSUPP';
case 10005:
return 'NFS4ERR_TOOSMALL';
case 10006:
return 'NFS4ERR_SERVERFAULT';
case 10007:
return 'NFS4ERR_BADTYPE';
case 10008:
return 'NFS4ERR_DELAY';
case 10009:
return 'NFS4ERR_SAME';
case 10010:
return 'NFS4ERR_DENIED';
case 10011:
return 'NFS4ERR_EXPIRED';
case 10012:
return 'NFS4ERR_LOCKED';
case 10013:
return 'NFS4ERR_GRACE';
case 10014:
return 'NFS4ERR_FHEXPIRED';
case 10015:
return 'NFS4ERR_SHARE_DENIED';
case 10016:
return 'NFS4ERR_WRONGSEC';
case 10017:
return 'NFS4ERR_CLID_INUSE';
case 10018:
return 'NFS4ERR_RESOURCE';
case 10019:
return 'NFS4ERR_MOVED';
case 10020:
return 'NFS4ERR_NOFILEHANDLE';
case 10021:
return 'NFS4ERR_MINOR_VERS_MISMATCH';
case 10022:
return 'NFS4ERR_STALE_CLIENTID';
case 10023:
return 'NFS4ERR_STALE_STATEID';
case 10024:
return 'NFS4ERR_OLD_STATEID';
case 10025:
return 'NFS4ERR_BAD_STATEID';
case 10026:
return 'NFS4ERR_BAD_SEQID';
case 10027:
return 'NFS4ERR_NOT_SAME';
case 10028:
return 'NFS4ERR_LOCK_RANGE';
case 10029:
return 'NFS4ERR_SYMLINK';
case 10030:
return 'NFS4ERR_RESTOREFH';
case 10031:
return 'NFS4ERR_LEASE_MOVED';
case 10032:
return 'NFS4ERR_ATTRNOTSUPP';
case 10033:
return 'NFS4ERR_NO_GRACE';
case 10034:
return 'NFS4ERR_RECLAIM_BAD';
case 10035:
return 'NFS4ERR_RECLAIM_CONFLICT';
case 10036:
return 'NFS4ERR_BADXDR';
case 10037:
return 'NFS4ERR_LOCKS_HELD';
case 10038:
return 'NFS4ERR_OPENMODE';
case 10039:
return 'NFS4ERR_BADOWNER';
case 10040:
return 'NFS4ERR_BADCHAR';
case 10041:
return 'NFS4ERR_BADNAME';
case 10042:
return 'NFS4ERR_BAD_RANGE';
case 10043:
return 'NFS4ERR_LOCK_NOTSUPP';
case 10044:
return 'NFS4ERR_OP_ILLEGAL';
case 10045:
return 'NFS4ERR_DEADLOCK';
case 10046:
return 'NFS4ERR_FILE_OPEN';
case 10047:
return 'NFS4ERR_ADMIN_REVOKED';
case 10048:
return 'NFS4ERR_CB_PATH_DOWN';
default:
return `Unknown(${stat})`;
}
};
exports.formatNfsv4Stat = formatNfsv4Stat;
const formatNfsv4Op = (op) => {
switch (op) {
case 3:
return 'ACCESS';
case 4:
return 'CLOSE';
case 5:
return 'COMMIT';
case 6:
return 'CREATE';
case 7:
return 'DELEGPURGE';
case 8:
return 'DELEGRETURN';
case 9:
return 'GETATTR';
case 10:
return 'GETFH';
case 11:
return 'LINK';
case 12:
return 'LOCK';
case 13:
return 'LOCKT';
case 14:
return 'LOCKU';
case 15:
return 'LOOKUP';
case 16:
return 'LOOKUPP';
case 17:
return 'NVERIFY';
case 18:
return 'OPEN';
case 19:
return 'OPENATTR';
case 20:
return 'OPEN_CONFIRM';
case 21:
return 'OPEN_DOWNGRADE';
case 22:
return 'PUTFH';
case 23:
return 'PUTPUBFH';
case 24:
return 'PUTROOTFH';
case 25:
return 'READ';
case 26:
return 'READDIR';
case 27:
return 'READLINK';
case 28:
return 'REMOVE';
case 29:
return 'RENAME';
case 30:
return 'RENEW';
case 31:
return 'RESTOREFH';
case 32:
return 'SAVEFH';
case 33:
return 'SECINFO';
case 34:
return 'SETATTR';
case 35:
return 'SETCLIENTID';
case 36:
return 'SETCLIENTID_CONFIRM';
case 37:
return 'VERIFY';
case 38:
return 'WRITE';
case 39:
return 'RELEASE_LOCKOWNER';
case 10044:
return 'ILLEGAL';
default:
return `Unknown(${op})`;
}
};
exports.formatNfsv4Op = formatNfsv4Op;
const formatNfsv4Attr = (attr) => {
switch (attr) {
case 0:
return 'supported_attrs';
case 1:
return 'type';
case 2:
return 'fh_expire_type';
case 3:
return 'change';
case 4:
return 'size';
case 5:
return 'link_support';
case 6:
return 'symlink_support';
case 7:
return 'named_attr';
case 8:
return 'fsid';
case 9:
return 'unique_handles';
case 10:
return 'lease_time';
case 11:
return 'rdattr_error';
case 12:
return 'acl';
case 13:
return 'aclsupport';
case 14:
return 'archive';
case 15:
return 'can_set_time';
case 16:
return 'case_insensitive';
case 17:
return 'case_preserving';
case 18:
return 'chown_restricted';
case 19:
return 'filehandle';
case 20:
return 'fileid';
case 21:
return 'files_avail';
case 22:
return 'files_free';
case 23:
return 'files_total';
case 24:
return 'fs_locations';
case 25:
return 'hidden';
case 26:
return 'homogeneous';
case 27:
return 'maxfilesize';
case 28:
return 'maxlink';
case 29:
return 'maxname';
case 30:
return 'maxread';
case 31:
return 'maxwrite';
case 32:
return 'mimetype';
case 33:
return 'mode';
case 34:
return 'no_trunc';
case 35:
return 'numlinks';
case 36:
return 'owner';
case 37:
return 'owner_group';
case 38:
return 'quota_avail_hard';
case 39:
return 'quota_avail_soft';
case 40:
return 'quota_used';
case 41:
return 'rawdev';
case 42:
return 'space_avail';
case 43:
return 'space_free';
case 44:
return 'space_total';
case 45:
return 'space_used';
case 46:
return 'system';
case 47:
return 'time_access';
case 48:
return 'time_access_set';
case 49:
return 'time_backup';
case 50:
return 'time_create';
case 51:
return 'time_delta';
case 52:
return 'time_metadata';
case 53:
return 'time_modify';
case 54:
return 'time_modify_set';
case 55:
return 'mounted_on_fileid';
default:
return `Unknown(${attr})`;
}
};
exports.formatNfsv4Attr = formatNfsv4Attr;
const formatNfsv4FType = (ftype) => {
switch (ftype) {
case 1:
return 'NF4REG';
case 2:
return 'NF4DIR';
case 3:
return 'NF4BLK';
case 4:
return 'NF4CHR';
case 5:
return 'NF4LNK';
case 6:
return 'NF4SOCK';
case 7:
return 'NF4FIFO';
case 8:
return 'NF4ATTRDIR';
case 9:
return 'NF4NAMEDATTR';
default:
return `Unknown(${ftype})`;
}
};
exports.formatNfsv4FType = formatNfsv4FType;
const formatNfsv4TimeHow = (how) => {
switch (how) {
case 0:
return 'SET_TO_SERVER_TIME4';
case 1:
return 'SET_TO_CLIENT_TIME4';
default:
return `Unknown(${how})`;
}
};
exports.formatNfsv4TimeHow = formatNfsv4TimeHow;
const formatNfsv4StableHow = (stable) => {
switch (stable) {
case 0:
return 'UNSTABLE4';
case 1:
return 'DATA_SYNC4';
case 2:
return 'FILE_SYNC4';
default:
return `Unknown(${stable})`;
}
};
exports.formatNfsv4StableHow = formatNfsv4StableHow;
const formatNfsv4CreateMode = (mode) => {
switch (mode) {
case 0:
return 'UNCHECKED4';
case 1:
return 'GUARDED4';
case 2:
return 'EXCLUSIVE4';
default:
return `Unknown(${mode})`;
}
};
exports.formatNfsv4CreateMode = formatNfsv4CreateMode;
const formatNfsv4OpenFlags = (flags) => {
switch (flags) {
case 0:
return 'OPEN4_NOCREATE';
case 1:
return 'OPEN4_CREATE';
default:
return `Unknown(${flags})`;
}
};
exports.formatNfsv4OpenFlags = formatNfsv4OpenFlags;
const formatNfsv4OpenAccess = (access) => {
switch (access) {
case 1:
return 'OPEN4_SHARE_ACCESS_READ';
case 2:
return 'OPEN4_SHARE_ACCESS_WRITE';
case 3:
return 'OPEN4_SHARE_ACCESS_BOTH';
default:
return `Unknown(${access})`;
}
};
exports.formatNfsv4OpenAccess = formatNfsv4OpenAccess;
const formatNfsv4OpenDeny = (deny) => {
switch (deny) {
case 0:
return 'OPEN4_SHARE_DENY_NONE';
case 1:
return 'OPEN4_SHARE_DENY_READ';
case 2:
return 'OPEN4_SHARE_DENY_WRITE';
case 3:
return 'OPEN4_SHARE_DENY_BOTH';
default:
return `Unknown(${deny})`;
}
};
exports.formatNfsv4OpenDeny = formatNfsv4OpenDeny;
const formatNfsv4OpenClaimType = (claim) => {
switch (claim) {
case 0:
return 'CLAIM_NULL';
case 1:
return 'CLAIM_PREVIOUS';
case 2:
return 'CLAIM_DELEGATE_CUR';
case 3:
return 'CLAIM_DELEGATE_PREV';
default:
return `Unknown(${claim})`;
}
};
exports.formatNfsv4OpenClaimType = formatNfsv4OpenClaimType;
const formatNfsv4DelegType = (deleg) => {
switch (deleg) {
case 0:
return 'OPEN_DELEGATE_NONE';
case 1:
return 'OPEN_DELEGATE_READ';
case 2:
return 'OPEN_DELEGATE_WRITE';
default:
return `Unknown(${deleg})`;
}
};
exports.formatNfsv4DelegType = formatNfsv4DelegType;
const formatNfsv4LockType = (locktype) => {
switch (locktype) {
case 1:
return 'READ_LT';
case 2:
return 'WRITE_LT';
case 3:
return 'READW_LT';
case 4:
return 'WRITEW_LT';
default:
return `Unknown(${locktype})`;
}
};
exports.formatNfsv4LockType = formatNfsv4LockType;
const formatNfsv4Access = (access) => {
const flags = [];
if (access & 1)
flags.push('READ');
if (access & 2)
flags.push('LOOKUP');
if (access & 4)
flags.push('MODIFY');
if (access & 8)
flags.push('EXTEND');
if (access & 16)
flags.push('DELETE');
if (access & 32)
flags.push('EXECUTE');
return flags.length > 0 ? flags.join('|') : `0x${access.toString(16)}`;
};
exports.formatNfsv4Access = formatNfsv4Access;
const formatNfsv4Mode = (mode) => {
const flags = [];
if (mode & 2048)
flags.push('SUID');
if (mode & 1024)
flags.push('SGID');
if (mode & 512)
flags.push('SVTX');
if (mode & 256)
flags.push('RUSR');
if (mode & 128)
flags.push('WUSR');
if (mode & 64)
flags.push('XUSR');
if (mode & 32)
flags.push('RGRP');
if (mode & 16)
flags.push('WGRP');
if (mode & 8)
flags.push('XGRP');
if (mode & 4)
flags.push('ROTH');
if (mode & 2)
flags.push('WOTH');
if (mode & 1)
flags.push('XOTH');
const octal = mode.toString(8).padStart(4, '0');
return flags.length > 0 ? `${octal} (${flags.join('|')})` : octal;
};
exports.formatNfsv4Mode = formatNfsv4Mode;
const formatNfsv4Bitmap = (bitmap) => {
const attrs = [];
const attrNums = (0, attributes_1.parseBitmask)(bitmap.mask);
for (const num of attrNums)
attrs.push((0, exports.formatNfsv4Attr)(num));
return attrs.length > 0 ? `[${attrs.join(', ')}]` : '[]';
};
exports.formatNfsv4Bitmap = formatNfsv4Bitmap;
const formatBytes = (data, maxLen = 32) => {
if (data.length === 0)
return '[]';
const hex = Array.from(data.slice(0, maxLen), (b) => b.toString(16).padStart(2, '0')).join(' ');
return data.length > maxLen ? `[${hex}... (${data.length} bytes)]` : `[${hex}]`;
};
const formatStateid = (stateid, tab = '') => {
return `Stateid { seqid = ${stateid.seqid}, other = ${formatBytes(stateid.other)} }`;
};
const formatFileHandle = (fh) => {
return formatBytes(fh.data, 16);
};
const formatNfsv4Request = (req, tab = '') => {
if (req instanceof msg.Nfsv4AccessRequest) {
return `ACCESS access = ${(0, exports.formatNfsv4Access)(req.access)}`;
}
else if (req instanceof msg.Nfsv4CloseRequest) {
return `CLOSE seqid = ${req.seqid}, stateid = ${formatStateid(req.openStateid, tab)}`;
}
else if (req instanceof msg.Nfsv4CommitRequest) {
return `COMMIT offset = ${req.offset}, count = ${req.count}`;
}
else if (req instanceof msg.Nfsv4CreateRequest) {
return `CREATE objtype = ${(0, exports.formatNfsv4FType)(req.objtype.type)}, objname = "${req.objname}"`;
}
else if (req instanceof msg.Nfsv4DelegpurgeRequest) {
return `DELEGPURGE clientid = ${req.clientid}`;
}
else if (req instanceof msg.Nfsv4DelegreturnRequest) {
return `DELEGRETURN stateid = ${formatStateid(req.delegStateid, tab)}`;
}
else if (req instanceof msg.Nfsv4GetattrRequest) {
return `GETATTR attrs = ${(0, exports.formatNfsv4Bitmap)(req.attrRequest)}`;
}
else if (req instanceof msg.Nfsv4GetfhRequest) {
return 'GETFH';
}
else if (req instanceof msg.Nfsv4LinkRequest) {
return `LINK newname = "${req.newname}"`;
}
else if (req instanceof msg.Nfsv4LockRequest) {
return `LOCK locktype = ${(0, exports.formatNfsv4LockType)(req.locktype)}, reclaim = ${req.reclaim}, offset = ${req.offset}, length = ${req.length}`;
}
else if (req instanceof msg.Nfsv4LocktRequest) {
return `LOCKT locktype = ${(0, exports.formatNfsv4LockType)(req.locktype)}, offset = ${req.offset}, length = ${req.length}`;
}
else if (req instanceof msg.Nfsv4LockuRequest) {
return `LOCKU locktype = ${(0, exports.formatNfsv4LockType)(req.locktype)}, seqid = ${req.seqid}, stateid = ${formatStateid(req.lockStateid, tab)}, offset = ${req.offset}, length = ${req.length}`;
}
else if (req instanceof msg.Nfsv4LookupRequest) {
return `LOOKUP objname = "${req.objname}"`;
}
else if (req instanceof msg.Nfsv4LookuppRequest) {
return 'LOOKUPP';
}
else if (req instanceof msg.Nfsv4NverifyRequest) {
return `NVERIFY attrs = ${(0, exports.formatNfsv4Bitmap)(req.objAttributes.attrmask)}`;
}
else if (req instanceof msg.Nfsv4OpenRequest) {
const createInfo = req.openhow.how ? `, createmode = ${(0, exports.formatNfsv4CreateMode)(req.openhow.how.mode)}` : '';
return `OPEN seqid = ${req.seqid}, shareAccess = ${(0, exports.formatNfsv4OpenAccess)(req.shareAccess)}, shareDeny = ${(0, exports.formatNfsv4OpenDeny)(req.shareDeny)}, opentype = ${(0, exports.formatNfsv4OpenFlags)(req.openhow.opentype)}${createInfo}, claim = ${(0, exports.formatNfsv4OpenClaimType)(req.claim.claimType)}`;
}
else if (req instanceof msg.Nfsv4OpenattrRequest) {
return `OPENATTR createdir = ${req.createdir}`;
}
else if (req instanceof msg.Nfsv4OpenConfirmRequest) {
return `OPEN_CONFIRM stateid = ${formatStateid(req.openStateid, tab)}, seqid = ${req.seqid}`;
}
else if (req instanceof msg.Nfsv4OpenDowngradeRequest) {
return `OPEN_DOWNGRADE stateid = ${formatStateid(req.openStateid, tab)}, seqid = ${req.seqid}, shareAccess = ${(0, exports.formatNfsv4OpenAccess)(req.shareAccess)}, shareDeny = ${(0, exports.formatNfsv4OpenDeny)(req.shareDeny)}`;
}
else if (req instanceof msg.Nfsv4PutfhRequest) {
return `PUTFH fh = ${formatFileHandle(req.object)}`;
}
else if (req instanceof msg.Nfsv4PutpubfhRequest) {
return 'PUTPUBFH';
}
else if (req instanceof msg.Nfsv4PutrootfhRequest) {
return 'PUTROOTFH';
}
else if (req instanceof msg.Nfsv4ReadRequest) {
return `READ stateid = ${formatStateid(req.stateid, tab)}, offset = ${req.offset}, count = ${req.count}`;
}
else if (req instanceof msg.Nfsv4ReaddirRequest) {
return `READDIR cookie = ${req.cookie}, dircount = ${req.dircount}, maxcount = ${req.maxcount}, attrs = ${(0, exports.formatNfsv4Bitmap)(req.attrRequest)}`;
}
else if (req instanceof msg.Nfsv4ReadlinkRequest) {
return 'READLINK';
}
else if (req instanceof msg.Nfsv4RemoveRequest) {
return `REMOVE target = "${req.target}"`;
}
else if (req instanceof msg.Nfsv4RenameRequest) {
return `RENAME oldname = "${req.oldname}", newname = "${req.newname}"`;
}
else if (req instanceof msg.Nfsv4RenewRequest) {
return `RENEW clientid = ${req.clientid}`;
}
else if (req instanceof msg.Nfsv4RestorefhRequest) {
return 'RESTOREFH';
}
else if (req instanceof msg.Nfsv4SavefhRequest) {
return 'SAVEFH';
}
else if (req instanceof msg.Nfsv4SecinfoRequest) {
return `SECINFO name = "${req.name}"`;
}
else if (req instanceof msg.Nfsv4SetattrRequest) {
return `SETATTR stateid = ${formatStateid(req.stateid, tab)}, attrs = ${(0, exports.formatNfsv4Bitmap)(req.objAttributes.attrmask)}`;
}
else if (req instanceof msg.Nfsv4SetclientidRequest) {
return `SETCLIENTID callbackIdent = ${req.callbackIdent}`;
}
else if (req instanceof msg.Nfsv4SetclientidConfirmRequest) {
return `SETCLIENTID_CONFIRM clientid = ${req.clientid}`;
}
else if (req instanceof msg.Nfsv4VerifyRequest) {
return `VERIFY attrs = ${(0, exports.formatNfsv4Bitmap)(req.objAttributes.attrmask)}`;
}
else if (req instanceof msg.Nfsv4WriteRequest) {
return `WRITE stateid = ${formatStateid(req.stateid, tab)}, offset = ${req.offset}, stable = ${(0, exports.formatNfsv4StableHow)(req.stable)}, length = ${req.data.length}`;
}
else if (req instanceof msg.Nfsv4ReleaseLockOwnerRequest) {
return 'RELEASE_LOCKOWNER';
}
else if (req instanceof msg.Nfsv4IllegalRequest) {
return 'ILLEGAL';
}
return 'Unknown Request';
};
exports.formatNfsv4Request = formatNfsv4Request;
const formatNfsv4Response = (res, tab = '') => {
if (res instanceof msg.Nfsv4AccessResponse) {
if (res.status === 0 && res.resok) {
return `ACCESS (${(0, exports.formatNfsv4Stat)(res.status)}) supported = ${(0, exports.formatNfsv4Access)(res.resok.supported)}, access = ${(0, exports.formatNfsv4Access)(res.resok.access)}`;
}
return `ACCESS (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4CloseResponse) {
const items = [];
if (res.status === 0 && res.resok) {
items.push((tab) => `stateid = ${formatStateid(res.resok.openStateid, tab)}`);
}
return `CLOSE (${(0, exports.formatNfsv4Stat)(res.status)})` + (0, printTree_1.printTree)(tab, items);
}
else if (res instanceof msg.Nfsv4CommitResponse) {
return `COMMIT (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4CreateResponse) {
return `CREATE (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4DelegpurgeResponse) {
return `DELEGPURGE (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4DelegreturnResponse) {
return `DELEGRETURN (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4GetattrResponse) {
const items = [];
if (res.status === 0 && res.resok) {
items.push((tab) => `attrs = ${(0, exports.formatNfsv4Bitmap)(res.resok.objAttributes.attrmask)}`);
}
return `GETATTR (${(0, exports.formatNfsv4Stat)(res.status)})` + (0, printTree_1.printTree)(tab, items);
}
else if (res instanceof msg.Nfsv4GetfhResponse) {
if (res.status === 0 && res.resok) {
return `GETFH (${(0, exports.formatNfsv4Stat)(res.status)}) fh = ${formatFileHandle(res.resok.object)}`;
}
return `GETFH (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4LinkResponse) {
return `LINK (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4LockResponse) {
if (res.status === 0 && res.resok) {
return `LOCK (${(0, exports.formatNfsv4Stat)(res.status)}) stateid = ${formatStateid(res.resok.lockStateid, tab)}`;
}
return `LOCK (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4LocktResponse) {
return `LOCKT (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4LockuResponse) {
if (res.status === 0 && res.resok) {
return `LOCKU (${(0, exports.formatNfsv4Stat)(res.status)}) stateid = ${formatStateid(res.resok.lockStateid, tab)}`;
}
return `LOCKU (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4LookupResponse) {
return `LOOKUP (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4LookuppResponse) {
return `LOOKUPP (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4NverifyResponse) {
return `NVERIFY (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4OpenResponse) {
if (res.status === 0 && res.resok) {
return `OPEN (${(0, exports.formatNfsv4Stat)(res.status)}) stateid = ${formatStateid(res.resok.stateid, tab)}`;
}
return `OPEN (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4OpenattrResponse) {
return `OPENATTR (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4OpenConfirmResponse) {
const items = [];
if (res.status === 0 && res.resok) {
items.push((tab) => `stateid = ${formatStateid(res.resok.openStateid, tab)}`);
}
return `OPEN_CONFIRM (${(0, exports.formatNfsv4Stat)(res.status)})` + (0, printTree_1.printTree)(tab, items);
}
else if (res instanceof msg.Nfsv4OpenDowngradeResponse) {
const items = [];
if (res.status === 0 && res.resok) {
items.push((tab) => `stateid = ${formatStateid(res.resok.openStateid, tab)}`);
}
return `OPEN_DOWNGRADE (${(0, exports.formatNfsv4Stat)(res.status)})` + (0, printTree_1.printTree)(tab, items);
}
else if (res instanceof msg.Nfsv4PutfhResponse) {
return `PUTFH (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4PutpubfhResponse) {
return `PUTPUBFH (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4PutrootfhResponse) {
return `PUTROOTFH (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4ReadResponse) {
if (res.status === 0 && res.resok) {
return `READ (${(0, exports.formatNfsv4Stat)(res.status)}) eof = ${res.resok.eof}, length = ${res.resok.data.length}`;
}
return `READ (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4ReaddirResponse) {
return `READDIR (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4ReadlinkResponse) {
const items = [];
if (res.status === 0 && res.resok) {
items.push((tab) => `link = "${res.resok.link}"`);
}
return `READLINK (${(0, exports.formatNfsv4Stat)(res.status)})` + (0, printTree_1.printTree)(tab, items);
}
else if (res instanceof msg.Nfsv4RemoveResponse) {
return `REMOVE (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4RenameResponse) {
return `RENAME (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4RenewResponse) {
return `RENEW (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4RestorefhResponse) {
return `RESTOREFH (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4SavefhResponse) {
return `SAVEFH (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4SecinfoResponse) {
return `SECINFO (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4SetattrResponse) {
const items = [];
if (res.status === 0 && res.resok) {
items.push((tab) => `attrsset = ${(0, exports.formatNfsv4Bitmap)(res.resok.attrsset)}`);
}
return `SETATTR (${(0, exports.formatNfsv4Stat)(res.status)})` + (0, printTree_1.printTree)(tab, items);
}
else if (res instanceof msg.Nfsv4SetclientidResponse) {
const items = [];
if (res.status === 0 && res.resok) {
items.push((tab) => `clientid = ${res.resok.clientid}`);
}
return `SETCLIENTID (${(0, exports.formatNfsv4Stat)(res.status)})` + (0, printTree_1.printTree)(tab, items);
}
else if (res instanceof msg.Nfsv4SetclientidConfirmResponse) {
return `SETCLIENTID_CONFIRM (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4VerifyResponse) {
return `VERIFY (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4WriteResponse) {
const items = [];
if (res.status === 0 && res.resok) {
items.push((tab) => `count = ${res.resok.count}`);
items.push((tab) => `committed = ${(0, exports.formatNfsv4StableHow)(res.resok.committed)}`);
}
return `WRITE (${(0, exports.formatNfsv4Stat)(res.status)})` + (0, printTree_1.printTree)(tab, items);
}
else if (res instanceof msg.Nfsv4ReleaseLockOwnerResponse) {
return `RELEASE_LOCKOWNER (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
else if (res instanceof msg.Nfsv4IllegalResponse) {
return `ILLEGAL (${(0, exports.formatNfsv4Stat)(res.status)})`;
}
return 'Unknown Response';
};
exports.formatNfsv4Response = formatNfsv4Response;
const formatNfsv4CompoundRequest = (req, tab = '') => {
const items = [
(tab) => `tag = "${req.tag}"`,
(tab) => `minorversion = ${req.minorversion}`,
];
req.argarray.forEach((op, i) => {
items.push((tab) => `[${i}] ${(0, exports.formatNfsv4Request)(op, tab)}`);
});
return 'COMPOUND' + (0, printTree_1.printTree)(tab, items);
};
exports.formatNfsv4CompoundRequest = formatNfsv4CompoundRequest;
const formatNfsv4CompoundResponse = (res, tab = '') => {
const items = [
(tab) => `status = ${(0, exports.formatNfsv4Stat)(res.status)}`,
(tab) => `tag = "${res.tag}"`,
];
res.resarray.forEach((op, i) => {
items.push((tab) => `[${i}] ${(0, exports.formatNfsv4Response)(op, tab)}`);
});
return 'COMPOUND' + (0, printTree_1.printTree)(tab, items);
};
exports.formatNfsv4CompoundResponse = formatNfsv4CompoundResponse;
//# sourceMappingURL=format.js.map
File diff suppressed because one or more lines are too long
+8
View File
@@ -0,0 +1,8 @@
export * from './constants';
export * from './structs';
export * from './messages';
export * from './builder';
export * from './Nfsv4Decoder';
export * from './Nfsv4Encoder';
export * from './Nfsv4FullEncoder';
export * from './format';
+12
View File
@@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
tslib_1.__exportStar(require("./constants"), exports);
tslib_1.__exportStar(require("./structs"), exports);
tslib_1.__exportStar(require("./messages"), exports);
tslib_1.__exportStar(require("./builder"), exports);
tslib_1.__exportStar(require("./Nfsv4Decoder"), exports);
tslib_1.__exportStar(require("./Nfsv4Encoder"), exports);
tslib_1.__exportStar(require("./Nfsv4FullEncoder"), exports);
tslib_1.__exportStar(require("./format"), exports);
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/nfs/v4/index.ts"],"names":[],"mappings":";;;AAAA,sDAA4B;AAC5B,oDAA0B;AAC1B,qDAA2B;AAC3B,oDAA0B;AAC1B,yDAA+B;AAC/B,yDAA+B;AAC/B,6DAAmC;AACnC,mDAAyB"}
+640
View File
@@ -0,0 +1,640 @@
import { Nfsv4Stat, type Nfsv4LockType } from './constants';
import * as structs from './structs';
import type { XdrDecoder, XdrEncoder, XdrType } from '../../xdr';
export type Nfsv4Operation = Nfsv4Request | Nfsv4Response;
export type Nfsv4Request = Nfsv4AccessRequest | Nfsv4CloseRequest | Nfsv4CommitRequest | Nfsv4CreateRequest | Nfsv4DelegpurgeRequest | Nfsv4DelegreturnRequest | Nfsv4GetattrRequest | Nfsv4GetfhRequest | Nfsv4LinkRequest | Nfsv4LockRequest | Nfsv4LocktRequest | Nfsv4LockuRequest | Nfsv4LookupRequest | Nfsv4LookuppRequest | Nfsv4NverifyRequest | Nfsv4OpenRequest | Nfsv4OpenattrRequest | Nfsv4OpenConfirmRequest | Nfsv4OpenDowngradeRequest | Nfsv4PutfhRequest | Nfsv4PutpubfhRequest | Nfsv4PutrootfhRequest | Nfsv4ReadRequest | Nfsv4ReaddirRequest | Nfsv4ReadlinkRequest | Nfsv4RemoveRequest | Nfsv4RenameRequest | Nfsv4RenewRequest | Nfsv4RestorefhRequest | Nfsv4SavefhRequest | Nfsv4SecinfoRequest | Nfsv4SetattrRequest | Nfsv4SetclientidRequest | Nfsv4SetclientidConfirmRequest | Nfsv4VerifyRequest | Nfsv4WriteRequest | Nfsv4ReleaseLockOwnerRequest | Nfsv4IllegalRequest;
export type Nfsv4Response = Nfsv4AccessResponse | Nfsv4CloseResponse | Nfsv4CommitResponse | Nfsv4CreateResponse | Nfsv4DelegpurgeResponse | Nfsv4DelegreturnResponse | Nfsv4GetattrResponse | Nfsv4GetfhResponse | Nfsv4LinkResponse | Nfsv4LockResponse | Nfsv4LocktResponse | Nfsv4LockuResponse | Nfsv4LookupResponse | Nfsv4LookuppResponse | Nfsv4NverifyResponse | Nfsv4OpenResponse | Nfsv4OpenattrResponse | Nfsv4OpenConfirmResponse | Nfsv4OpenDowngradeResponse | Nfsv4PutfhResponse | Nfsv4PutpubfhResponse | Nfsv4PutrootfhResponse | Nfsv4ReadResponse | Nfsv4ReaddirResponse | Nfsv4ReadlinkResponse | Nfsv4RemoveResponse | Nfsv4RenameResponse | Nfsv4RenewResponse | Nfsv4RestorefhResponse | Nfsv4SavefhResponse | Nfsv4SecinfoResponse | Nfsv4SetattrResponse | Nfsv4SetclientidResponse | Nfsv4SetclientidConfirmResponse | Nfsv4VerifyResponse | Nfsv4WriteResponse | Nfsv4ReleaseLockOwnerResponse | Nfsv4IllegalResponse;
export declare class Nfsv4AccessRequest implements XdrType {
readonly access: number;
static decode(xdr: XdrDecoder): Nfsv4AccessRequest;
constructor(access: number);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4AccessResOk {
readonly supported: number;
readonly access: number;
constructor(supported: number, access: number);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4AccessResponse implements XdrType {
readonly status: Nfsv4Stat;
readonly resok?: Nfsv4AccessResOk | undefined;
constructor(status: Nfsv4Stat, resok?: Nfsv4AccessResOk | undefined);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4CloseRequest {
readonly seqid: number;
readonly openStateid: structs.Nfsv4Stateid;
static decode(xdr: XdrDecoder): Nfsv4CloseRequest;
constructor(seqid: number, openStateid: structs.Nfsv4Stateid);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4CloseResOk {
readonly openStateid: structs.Nfsv4Stateid;
constructor(openStateid: structs.Nfsv4Stateid);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4CloseResponse implements XdrType {
readonly status: Nfsv4Stat;
readonly resok?: Nfsv4CloseResOk | undefined;
constructor(status: Nfsv4Stat, resok?: Nfsv4CloseResOk | undefined);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4CommitRequest implements XdrType {
readonly offset: bigint;
readonly count: number;
static decode(xdr: XdrDecoder): Nfsv4CommitRequest;
constructor(offset: bigint, count: number);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4CommitResOk {
readonly writeverf: structs.Nfsv4Verifier;
constructor(writeverf: structs.Nfsv4Verifier);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4CommitResponse implements XdrType {
readonly status: Nfsv4Stat;
readonly resok?: Nfsv4CommitResOk | undefined;
constructor(status: Nfsv4Stat, resok?: Nfsv4CommitResOk | undefined);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4CreateRequest implements XdrType {
readonly objtype: structs.Nfsv4CreateType;
readonly objname: string;
readonly createattrs: structs.Nfsv4Fattr;
constructor(objtype: structs.Nfsv4CreateType, objname: string, createattrs: structs.Nfsv4Fattr);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4CreateResOk {
readonly cinfo: structs.Nfsv4ChangeInfo;
readonly attrset: structs.Nfsv4Bitmap;
constructor(cinfo: structs.Nfsv4ChangeInfo, attrset: structs.Nfsv4Bitmap);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4CreateResponse implements XdrType {
readonly status: Nfsv4Stat;
readonly resok?: Nfsv4CreateResOk | undefined;
constructor(status: Nfsv4Stat, resok?: Nfsv4CreateResOk | undefined);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4DelegpurgeRequest implements XdrType {
readonly clientid: bigint;
static decode(xdr: XdrDecoder): Nfsv4DelegpurgeRequest;
constructor(clientid: bigint);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4DelegpurgeResponse implements XdrType {
readonly status: Nfsv4Stat;
constructor(status: Nfsv4Stat);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4DelegreturnRequest implements XdrType {
readonly delegStateid: structs.Nfsv4Stateid;
static decode(xdr: XdrDecoder): Nfsv4DelegreturnRequest;
constructor(delegStateid: structs.Nfsv4Stateid);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4DelegreturnResponse implements XdrType {
readonly status: Nfsv4Stat;
constructor(status: Nfsv4Stat);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4GetattrRequest implements XdrType {
readonly attrRequest: structs.Nfsv4Bitmap;
constructor(attrRequest: structs.Nfsv4Bitmap);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4GetattrResOk {
readonly objAttributes: structs.Nfsv4Fattr;
constructor(objAttributes: structs.Nfsv4Fattr);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4GetattrResponse implements XdrType {
readonly status: Nfsv4Stat;
readonly resok?: Nfsv4GetattrResOk | undefined;
constructor(status: Nfsv4Stat, resok?: Nfsv4GetattrResOk | undefined);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4GetfhRequest implements XdrType {
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4GetfhResOk {
readonly object: structs.Nfsv4Fh;
constructor(object: structs.Nfsv4Fh);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4GetfhResponse implements XdrType {
readonly status: Nfsv4Stat;
readonly resok?: Nfsv4GetfhResOk | undefined;
constructor(status: Nfsv4Stat, resok?: Nfsv4GetfhResOk | undefined);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4LinkRequest implements XdrType {
readonly newname: string;
constructor(newname: string);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4LinkResOk {
readonly cinfo: structs.Nfsv4ChangeInfo;
constructor(cinfo: structs.Nfsv4ChangeInfo);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4LinkResponse implements XdrType {
readonly status: Nfsv4Stat;
readonly resok?: Nfsv4LinkResOk | undefined;
constructor(status: Nfsv4Stat, resok?: Nfsv4LinkResOk | undefined);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4LockRequest implements XdrType {
readonly locktype: Nfsv4LockType;
readonly reclaim: boolean;
readonly offset: bigint;
readonly length: bigint;
readonly locker: structs.Nfsv4LockOwnerInfo;
constructor(locktype: Nfsv4LockType, reclaim: boolean, offset: bigint, length: bigint, locker: structs.Nfsv4LockOwnerInfo);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4LockResOk {
readonly lockStateid: structs.Nfsv4Stateid;
constructor(lockStateid: structs.Nfsv4Stateid);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4LockResDenied {
readonly offset: bigint;
readonly length: bigint;
readonly locktype: Nfsv4LockType;
readonly owner: structs.Nfsv4LockOwner;
constructor(offset: bigint, length: bigint, locktype: Nfsv4LockType, owner: structs.Nfsv4LockOwner);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4LockResponse implements XdrType {
readonly status: Nfsv4Stat;
readonly resok?: Nfsv4LockResOk | undefined;
readonly denied?: Nfsv4LockResDenied | undefined;
constructor(status: Nfsv4Stat, resok?: Nfsv4LockResOk | undefined, denied?: Nfsv4LockResDenied | undefined);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4LocktRequest implements XdrType {
readonly locktype: Nfsv4LockType;
readonly offset: bigint;
readonly length: bigint;
readonly owner: structs.Nfsv4LockOwner;
constructor(locktype: Nfsv4LockType, offset: bigint, length: bigint, owner: structs.Nfsv4LockOwner);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4LocktResDenied {
readonly offset: bigint;
readonly length: bigint;
readonly locktype: Nfsv4LockType;
readonly owner: structs.Nfsv4LockOwner;
constructor(offset: bigint, length: bigint, locktype: Nfsv4LockType, owner: structs.Nfsv4LockOwner);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4LocktResponse implements XdrType {
readonly status: Nfsv4Stat;
readonly denied?: Nfsv4LocktResDenied | undefined;
constructor(status: Nfsv4Stat, denied?: Nfsv4LocktResDenied | undefined);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4LockuRequest implements XdrType {
readonly locktype: Nfsv4LockType;
readonly seqid: number;
readonly lockStateid: structs.Nfsv4Stateid;
readonly offset: bigint;
readonly length: bigint;
constructor(locktype: Nfsv4LockType, seqid: number, lockStateid: structs.Nfsv4Stateid, offset: bigint, length: bigint);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4LockuResOk {
readonly lockStateid: structs.Nfsv4Stateid;
constructor(lockStateid: structs.Nfsv4Stateid);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4LockuResponse implements XdrType {
readonly status: Nfsv4Stat;
readonly resok?: Nfsv4LockuResOk | undefined;
constructor(status: Nfsv4Stat, resok?: Nfsv4LockuResOk | undefined);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4LookupRequest implements XdrType {
readonly objname: string;
constructor(objname: string);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4LookupResponse implements XdrType {
readonly status: Nfsv4Stat;
constructor(status: Nfsv4Stat);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4LookuppRequest implements XdrType {
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4LookuppResponse implements XdrType {
readonly status: Nfsv4Stat;
constructor(status: Nfsv4Stat);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4NverifyRequest implements XdrType {
readonly objAttributes: structs.Nfsv4Fattr;
constructor(objAttributes: structs.Nfsv4Fattr);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4NverifyResponse implements XdrType {
readonly status: Nfsv4Stat;
constructor(status: Nfsv4Stat);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4OpenRequest implements XdrType {
readonly seqid: number;
readonly shareAccess: number;
readonly shareDeny: number;
readonly owner: structs.Nfsv4OpenOwner;
readonly openhow: structs.Nfsv4OpenHow;
readonly claim: structs.Nfsv4OpenClaim;
constructor(seqid: number, shareAccess: number, shareDeny: number, owner: structs.Nfsv4OpenOwner, openhow: structs.Nfsv4OpenHow, claim: structs.Nfsv4OpenClaim);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4OpenResOk {
readonly stateid: structs.Nfsv4Stateid;
readonly cinfo: structs.Nfsv4ChangeInfo;
readonly rflags: number;
readonly attrset: structs.Nfsv4Bitmap;
readonly delegation: structs.Nfsv4OpenDelegation;
constructor(stateid: structs.Nfsv4Stateid, cinfo: structs.Nfsv4ChangeInfo, rflags: number, attrset: structs.Nfsv4Bitmap, delegation: structs.Nfsv4OpenDelegation);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4OpenResponse implements XdrType {
readonly status: Nfsv4Stat;
readonly resok?: Nfsv4OpenResOk | undefined;
constructor(status: Nfsv4Stat, resok?: Nfsv4OpenResOk | undefined);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4OpenattrRequest implements XdrType {
readonly createdir: boolean;
constructor(createdir: boolean);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4OpenattrResponse implements XdrType {
readonly status: Nfsv4Stat;
constructor(status: Nfsv4Stat);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4OpenConfirmRequest implements XdrType {
readonly openStateid: structs.Nfsv4Stateid;
readonly seqid: number;
constructor(openStateid: structs.Nfsv4Stateid, seqid: number);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4OpenConfirmResOk {
readonly openStateid: structs.Nfsv4Stateid;
constructor(openStateid: structs.Nfsv4Stateid);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4OpenConfirmResponse implements XdrType {
readonly status: Nfsv4Stat;
readonly resok?: Nfsv4OpenConfirmResOk | undefined;
constructor(status: Nfsv4Stat, resok?: Nfsv4OpenConfirmResOk | undefined);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4OpenDowngradeRequest implements XdrType {
readonly openStateid: structs.Nfsv4Stateid;
readonly seqid: number;
readonly shareAccess: number;
readonly shareDeny: number;
constructor(openStateid: structs.Nfsv4Stateid, seqid: number, shareAccess: number, shareDeny: number);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4OpenDowngradeResOk {
readonly openStateid: structs.Nfsv4Stateid;
constructor(openStateid: structs.Nfsv4Stateid);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4OpenDowngradeResponse implements XdrType {
readonly status: Nfsv4Stat;
readonly resok?: Nfsv4OpenDowngradeResOk | undefined;
constructor(status: Nfsv4Stat, resok?: Nfsv4OpenDowngradeResOk | undefined);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4PutfhRequest implements XdrType {
readonly object: structs.Nfsv4Fh;
constructor(object: structs.Nfsv4Fh);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4PutfhResponse implements XdrType {
readonly status: Nfsv4Stat;
constructor(status: Nfsv4Stat);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4PutpubfhRequest implements XdrType {
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4PutpubfhResponse implements XdrType {
readonly status: Nfsv4Stat;
static decode(xdr: XdrDecoder): Nfsv4PutpubfhResponse;
constructor(status: Nfsv4Stat);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4PutrootfhRequest implements XdrType {
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4PutrootfhResponse implements XdrType {
readonly status: Nfsv4Stat;
constructor(status: Nfsv4Stat);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4ReadRequest implements XdrType {
readonly stateid: structs.Nfsv4Stateid;
readonly offset: bigint;
readonly count: number;
constructor(stateid: structs.Nfsv4Stateid, offset: bigint, count: number);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4ReadResOk {
readonly eof: boolean;
readonly data: Uint8Array;
constructor(eof: boolean, data: Uint8Array);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4ReadResponse implements XdrType {
readonly status: Nfsv4Stat;
readonly resok?: Nfsv4ReadResOk | undefined;
constructor(status: Nfsv4Stat, resok?: Nfsv4ReadResOk | undefined);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4ReaddirRequest implements XdrType {
readonly cookie: bigint;
readonly cookieverf: structs.Nfsv4Verifier;
readonly dircount: number;
readonly maxcount: number;
readonly attrRequest: structs.Nfsv4Bitmap;
constructor(cookie: bigint, cookieverf: structs.Nfsv4Verifier, dircount: number, maxcount: number, attrRequest: structs.Nfsv4Bitmap);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4ReaddirResOk {
readonly cookieverf: structs.Nfsv4Verifier;
readonly entries: structs.Nfsv4Entry[];
readonly eof: boolean;
constructor(cookieverf: structs.Nfsv4Verifier, entries: structs.Nfsv4Entry[], eof: boolean);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4ReaddirResponse implements XdrType {
readonly status: Nfsv4Stat;
readonly resok?: Nfsv4ReaddirResOk | undefined;
constructor(status: Nfsv4Stat, resok?: Nfsv4ReaddirResOk | undefined);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4ReadlinkRequest implements XdrType {
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4ReadlinkResOk {
readonly link: string;
constructor(link: string);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4ReadlinkResponse implements XdrType {
readonly status: Nfsv4Stat;
readonly resok?: Nfsv4ReadlinkResOk | undefined;
constructor(status: Nfsv4Stat, resok?: Nfsv4ReadlinkResOk | undefined);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4RemoveRequest implements XdrType {
readonly target: string;
constructor(target: string);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4RemoveResOk {
readonly cinfo: structs.Nfsv4ChangeInfo;
constructor(cinfo: structs.Nfsv4ChangeInfo);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4RemoveResponse implements XdrType {
readonly status: Nfsv4Stat;
readonly resok?: Nfsv4RemoveResOk | undefined;
constructor(status: Nfsv4Stat, resok?: Nfsv4RemoveResOk | undefined);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4RenameRequest implements XdrType {
readonly oldname: string;
readonly newname: string;
constructor(oldname: string, newname: string);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4RenameResOk {
readonly sourceCinfo: structs.Nfsv4ChangeInfo;
readonly targetCinfo: structs.Nfsv4ChangeInfo;
constructor(sourceCinfo: structs.Nfsv4ChangeInfo, targetCinfo: structs.Nfsv4ChangeInfo);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4RenameResponse implements XdrType {
readonly status: Nfsv4Stat;
readonly resok?: Nfsv4RenameResOk | undefined;
constructor(status: Nfsv4Stat, resok?: Nfsv4RenameResOk | undefined);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4RenewRequest implements XdrType {
readonly clientid: bigint;
constructor(clientid: bigint);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4RenewResponse implements XdrType {
readonly status: Nfsv4Stat;
constructor(status: Nfsv4Stat);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4RestorefhRequest implements XdrType {
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4RestorefhResponse implements XdrType {
readonly status: Nfsv4Stat;
constructor(status: Nfsv4Stat);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4SavefhRequest implements XdrType {
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4SavefhResponse implements XdrType {
readonly status: Nfsv4Stat;
constructor(status: Nfsv4Stat);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4SecinfoRequest implements XdrType {
readonly name: string;
constructor(name: string);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4SecinfoResOk {
readonly flavors: structs.Nfsv4SecInfoFlavor[];
constructor(flavors: structs.Nfsv4SecInfoFlavor[]);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4SecinfoResponse implements XdrType {
readonly status: Nfsv4Stat;
readonly resok?: Nfsv4SecinfoResOk | undefined;
constructor(status: Nfsv4Stat, resok?: Nfsv4SecinfoResOk | undefined);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4SetattrRequest implements XdrType {
readonly stateid: structs.Nfsv4Stateid;
readonly objAttributes: structs.Nfsv4Fattr;
constructor(stateid: structs.Nfsv4Stateid, objAttributes: structs.Nfsv4Fattr);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4SetattrResOk {
readonly attrsset: structs.Nfsv4Bitmap;
constructor(attrsset: structs.Nfsv4Bitmap);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4SetattrResponse implements XdrType {
readonly status: Nfsv4Stat;
readonly resok?: Nfsv4SetattrResOk | undefined;
constructor(status: Nfsv4Stat, resok?: Nfsv4SetattrResOk | undefined);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4SetclientidRequest implements XdrType {
readonly client: structs.Nfsv4ClientId;
readonly callback: structs.Nfsv4CbClient;
readonly callbackIdent: number;
constructor(client: structs.Nfsv4ClientId, callback: structs.Nfsv4CbClient, callbackIdent: number);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4SetclientidResOk {
readonly clientid: bigint;
readonly setclientidConfirm: structs.Nfsv4Verifier;
constructor(clientid: bigint, setclientidConfirm: structs.Nfsv4Verifier);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4SetclientidResponse implements XdrType {
readonly status: Nfsv4Stat;
readonly resok?: Nfsv4SetclientidResOk | undefined;
constructor(status: Nfsv4Stat, resok?: Nfsv4SetclientidResOk | undefined);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4SetclientidConfirmRequest implements XdrType {
readonly clientid: bigint;
readonly setclientidConfirm: structs.Nfsv4Verifier;
constructor(clientid: bigint, setclientidConfirm: structs.Nfsv4Verifier);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4SetclientidConfirmResponse implements XdrType {
readonly status: Nfsv4Stat;
constructor(status: Nfsv4Stat);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4VerifyRequest implements XdrType {
readonly objAttributes: structs.Nfsv4Fattr;
constructor(objAttributes: structs.Nfsv4Fattr);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4VerifyResponse implements XdrType {
readonly status: Nfsv4Stat;
constructor(status: Nfsv4Stat);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4WriteRequest implements XdrType {
readonly stateid: structs.Nfsv4Stateid;
readonly offset: bigint;
readonly stable: number;
readonly data: Uint8Array;
constructor(stateid: structs.Nfsv4Stateid, offset: bigint, stable: number, data: Uint8Array);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4WriteResOk {
readonly count: number;
readonly committed: number;
readonly writeverf: structs.Nfsv4Verifier;
constructor(count: number, committed: number, writeverf: structs.Nfsv4Verifier);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4WriteResponse implements XdrType {
readonly status: Nfsv4Stat;
readonly resok?: Nfsv4WriteResOk | undefined;
constructor(status: Nfsv4Stat, resok?: Nfsv4WriteResOk | undefined);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4ReleaseLockOwnerRequest implements XdrType {
readonly lockOwner: structs.Nfsv4LockOwner;
constructor(lockOwner: structs.Nfsv4LockOwner);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4ReleaseLockOwnerResponse implements XdrType {
readonly status: Nfsv4Stat;
constructor(status: Nfsv4Stat);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4IllegalRequest implements XdrType {
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4IllegalResponse implements XdrType {
readonly status: Nfsv4Stat;
constructor(status: Nfsv4Stat);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4CompoundRequest implements XdrType {
readonly tag: string;
readonly minorversion: number;
readonly argarray: Nfsv4Request[];
constructor(tag: string, minorversion: number, argarray: Nfsv4Request[]);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4CompoundResponse implements XdrType {
readonly status: Nfsv4Stat;
readonly tag: string;
readonly resarray: Nfsv4Response[];
constructor(status: Nfsv4Stat, tag: string, resarray: Nfsv4Response[]);
encode(xdr: XdrEncoder): void;
}
export type Nfsv4CbOperation = Nfsv4CbRequest | Nfsv4CbResponse;
export type Nfsv4CbRequest = Nfsv4CbGetattrRequest | Nfsv4CbRecallRequest | Nfsv4CbIllegalRequest;
export type Nfsv4CbResponse = Nfsv4CbGetattrResponse | Nfsv4CbRecallResponse | Nfsv4CbIllegalResponse;
export declare class Nfsv4CbGetattrRequest implements XdrType {
readonly fh: structs.Nfsv4Fh;
readonly attrRequest: structs.Nfsv4Bitmap;
constructor(fh: structs.Nfsv4Fh, attrRequest: structs.Nfsv4Bitmap);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4CbGetattrResOk {
readonly objAttributes: structs.Nfsv4Fattr;
constructor(objAttributes: structs.Nfsv4Fattr);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4CbGetattrResponse implements XdrType {
readonly status: Nfsv4Stat;
readonly resok?: Nfsv4CbGetattrResOk | undefined;
constructor(status: Nfsv4Stat, resok?: Nfsv4CbGetattrResOk | undefined);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4CbRecallRequest implements XdrType {
readonly stateid: structs.Nfsv4Stateid;
readonly truncate: boolean;
readonly fh: structs.Nfsv4Fh;
constructor(stateid: structs.Nfsv4Stateid, truncate: boolean, fh: structs.Nfsv4Fh);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4CbRecallResponse implements XdrType {
readonly status: Nfsv4Stat;
constructor(status: Nfsv4Stat);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4CbIllegalRequest implements XdrType {
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4CbIllegalResponse implements XdrType {
readonly status: Nfsv4Stat;
constructor(status: Nfsv4Stat);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4CbCompoundRequest implements XdrType {
readonly tag: string;
readonly minorversion: number;
readonly callbackIdent: number;
readonly argarray: Nfsv4CbRequest[];
constructor(tag: string, minorversion: number, callbackIdent: number, argarray: Nfsv4CbRequest[]);
encode(xdr: XdrEncoder): void;
}
export declare class Nfsv4CbCompoundResponse implements XdrType {
readonly status: Nfsv4Stat;
readonly tag: string;
readonly resarray: Nfsv4CbResponse[];
constructor(status: Nfsv4Stat, tag: string, resarray: Nfsv4CbResponse[]);
encode(xdr: XdrEncoder): void;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,11 @@
import { Nfsv4Connection } from './Nfsv4Connection';
import * as msg from '../messages';
export declare class Nfsv4CompoundProcCtx {
readonly connection: Nfsv4Connection;
readonly req: msg.Nfsv4CompoundRequest;
cfh: Uint8Array | null;
sfh: Uint8Array | null;
constructor(connection: Nfsv4Connection, req: msg.Nfsv4CompoundRequest);
getPrincipal(): string;
exec(): Promise<msg.Nfsv4CompoundResponse>;
}
@@ -0,0 +1,155 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Nfsv4CompoundProcCtx = void 0;
const tslib_1 = require("tslib");
const msg = tslib_1.__importStar(require("../messages"));
const format_1 = require("../format");
class Nfsv4CompoundProcCtx {
constructor(connection, req) {
this.connection = connection;
this.req = req;
this.cfh = null;
this.sfh = null;
}
getPrincipal() {
return 'none';
}
async exec() {
const { req, connection } = this;
const { ops, debug, logger } = connection;
const { argarray, tag } = req;
const length = argarray.length;
let status = 0;
const resarray = [];
OPS_LOOP: for (let i = 0; i < length; i++) {
const op = argarray[i];
const opReq = op;
let fn = void 0;
let Response = void 0;
if (op instanceof msg.Nfsv4AccessRequest)
(fn = ops.ACCESS), (Response = msg.Nfsv4AccessResponse);
else if (op instanceof msg.Nfsv4PutrootfhRequest)
(fn = ops.PUTROOTFH), (Response = msg.Nfsv4PutrootfhResponse);
else if (op instanceof msg.Nfsv4PutpubfhRequest)
(fn = ops.PUTPUBFH), (Response = msg.Nfsv4PutpubfhResponse);
else if (op instanceof msg.Nfsv4PutfhRequest)
(fn = ops.PUTFH), (Response = msg.Nfsv4PutfhResponse);
else if (op instanceof msg.Nfsv4GetfhRequest)
(fn = ops.GETFH), (Response = msg.Nfsv4GetfhResponse);
else if (op instanceof msg.Nfsv4SavefhRequest)
(fn = ops.SAVEFH), (Response = msg.Nfsv4SavefhResponse);
else if (op instanceof msg.Nfsv4ReadRequest)
(fn = ops.READ), (Response = msg.Nfsv4ReadResponse);
else if (op instanceof msg.Nfsv4ReaddirRequest)
(fn = ops.READDIR), (Response = msg.Nfsv4ReaddirResponse);
else if (op instanceof msg.Nfsv4ReadlinkRequest)
(fn = ops.READLINK), (Response = msg.Nfsv4ReadlinkResponse);
else if (op instanceof msg.Nfsv4WriteRequest)
(fn = ops.WRITE), (Response = msg.Nfsv4WriteResponse);
else if (op instanceof msg.Nfsv4OpenRequest)
(fn = ops.OPEN), (Response = msg.Nfsv4OpenResponse);
else if (op instanceof msg.Nfsv4CloseRequest)
(fn = ops.CLOSE), (Response = msg.Nfsv4CloseResponse);
else if (op instanceof msg.Nfsv4RemoveRequest)
(fn = ops.REMOVE), (Response = msg.Nfsv4RemoveResponse);
else if (op instanceof msg.Nfsv4RenameRequest)
(fn = ops.RENAME), (Response = msg.Nfsv4RenameResponse);
else if (op instanceof msg.Nfsv4OpenattrRequest)
(fn = ops.OPENATTR), (Response = msg.Nfsv4OpenattrResponse);
else if (op instanceof msg.Nfsv4GetattrRequest)
(fn = ops.GETATTR), (Response = msg.Nfsv4GetattrResponse);
else if (op instanceof msg.Nfsv4SetattrRequest)
(fn = ops.SETATTR), (Response = msg.Nfsv4SetattrResponse);
else if (op instanceof msg.Nfsv4CreateRequest)
(fn = ops.CREATE), (Response = msg.Nfsv4CreateResponse);
else if (op instanceof msg.Nfsv4SetclientidRequest)
(fn = ops.SETCLIENTID), (Response = msg.Nfsv4SetclientidResponse);
else if (op instanceof msg.Nfsv4SetclientidConfirmRequest)
(fn = ops.SETCLIENTID_CONFIRM), (Response = msg.Nfsv4SetclientidConfirmResponse);
else if (op instanceof msg.Nfsv4OpenConfirmRequest)
(fn = ops.OPEN_CONFIRM), (Response = msg.Nfsv4OpenConfirmResponse);
else if (op instanceof msg.Nfsv4OpenDowngradeRequest)
(fn = ops.OPEN_DOWNGRADE), (Response = msg.Nfsv4OpenDowngradeResponse);
else if (op instanceof msg.Nfsv4CommitRequest)
(fn = ops.COMMIT), (Response = msg.Nfsv4CommitResponse);
else if (op instanceof msg.Nfsv4LinkRequest)
(fn = ops.LINK), (Response = msg.Nfsv4LinkResponse);
else if (op instanceof msg.Nfsv4RenewRequest)
(fn = ops.RENEW), (Response = msg.Nfsv4RenewResponse);
else if (op instanceof msg.Nfsv4DelegpurgeRequest)
(fn = ops.DELEGPURGE), (Response = msg.Nfsv4DelegpurgeResponse);
else if (op instanceof msg.Nfsv4DelegreturnRequest)
(fn = ops.DELEGRETURN), (Response = msg.Nfsv4DelegreturnResponse);
else if (op instanceof msg.Nfsv4RestorefhRequest)
(fn = ops.RESTOREFH), (Response = msg.Nfsv4RestorefhResponse);
else if (op instanceof msg.Nfsv4SecinfoRequest)
(fn = ops.SECINFO), (Response = msg.Nfsv4SecinfoResponse);
else if (op instanceof msg.Nfsv4VerifyRequest)
(fn = ops.VERIFY), (Response = msg.Nfsv4VerifyResponse);
else if (op instanceof msg.Nfsv4LockRequest)
(fn = ops.LOCK), (Response = msg.Nfsv4LockResponse);
else if (op instanceof msg.Nfsv4LocktRequest)
(fn = ops.LOCKT), (Response = msg.Nfsv4LocktResponse);
else if (op instanceof msg.Nfsv4LockuRequest)
(fn = ops.LOCKU), (Response = msg.Nfsv4LockuResponse);
else if (op instanceof msg.Nfsv4LookupRequest)
(fn = ops.LOOKUP), (Response = msg.Nfsv4LookupResponse);
else if (op instanceof msg.Nfsv4LookuppRequest)
(fn = ops.LOOKUPP), (Response = msg.Nfsv4LookuppResponse);
else if (op instanceof msg.Nfsv4NverifyRequest)
(fn = ops.NVERIFY), (Response = msg.Nfsv4NverifyResponse);
else if (op instanceof msg.Nfsv4ReleaseLockOwnerRequest)
(fn = ops.RELEASE_LOCKOWNER), (Response = msg.Nfsv4ReleaseLockOwnerResponse);
else if (op instanceof msg.Nfsv4IllegalRequest)
(fn = ops.ILLEGAL), (Response = msg.Nfsv4IllegalResponse);
if (!fn || !Response)
return new msg.Nfsv4CompoundResponse(10044, tag, resarray);
EXEC_OP: try {
if (debug)
logger.log((0, format_1.formatNfsv4Request)(opReq));
const opResponse = await fn.call(ops, opReq, this);
if (!(opResponse instanceof Response))
throw new Error('Unexpected response, fn = ' + fn.name);
if (debug)
logger.log(': ' + (0, format_1.formatNfsv4Response)(opResponse));
status = opResponse.status;
resarray.push(opResponse);
}
catch (err) {
if (debug)
logger.error(': ERROR', fn.name, err);
if (err instanceof Response) {
if (err.status !== 0) {
status = err.status;
resarray.push(err);
break EXEC_OP;
}
else {
logger.error('Operation [' + fn.name + '] threw response with NFS4_OK');
err = 10006;
}
}
FIND_STATUS_CODE: {
if (typeof err === 'number') {
if (err > 0 && err <= 16777215) {
status = err;
break FIND_STATUS_CODE;
}
status = 10006;
logger.error('Invalid status [code = ' + err + ', fn = ' + fn.name + ']');
break FIND_STATUS_CODE;
}
status = 10006;
logger.error(fn.name, err);
}
const opResponse = new Response(status);
resarray.push(opResponse);
}
if (status !== 0)
break OPS_LOOP;
}
return new msg.Nfsv4CompoundResponse(status, tag, resarray);
}
}
exports.Nfsv4CompoundProcCtx = Nfsv4CompoundProcCtx;
//# sourceMappingURL=Nfsv4CompoundProcCtx.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,42 @@
/// <reference types="node" />
import { Nfsv4Decoder } from '../Nfsv4Decoder';
import { Nfsv4FullEncoder } from '../Nfsv4FullEncoder';
import { RmRecordDecoder, RmRecordEncoder } from '../../../rm';
import { RpcCallMessage, RpcMessage, RpcMessageDecoder, RpcMessageEncoder } from '../../../rpc';
import type { Duplex } from 'node:stream';
import type { IWriter, IWriterGrowable } from '@jsonjoy.com/buffers/lib/types';
import type { Nfsv4Operations } from './operations/Nfsv4Operations';
export interface Nfsv4ConnectionOpts {
duplex: Duplex;
ops: Nfsv4Operations;
encoder?: Nfsv4FullEncoder;
decoder?: Nfsv4Decoder;
debug?: boolean;
logger?: Pick<typeof console, 'log' | 'error'>;
}
export declare class Nfsv4Connection {
closed: boolean;
maxIncomingMessage: number;
maxBackpressure: number;
protected lastXid: number;
readonly duplex: Duplex;
protected readonly rmDecoder: RmRecordDecoder;
protected readonly rpcDecoder: RpcMessageDecoder;
protected readonly nfsDecoder: Nfsv4Decoder;
protected readonly writer: IWriter & IWriterGrowable;
protected readonly rmEncoder: RmRecordEncoder;
protected readonly rpcEncoder: RpcMessageEncoder;
protected readonly nfsEncoder: Nfsv4FullEncoder;
debug: boolean;
logger: Pick<typeof console, 'log' | 'error'>;
readonly ops: Nfsv4Operations;
constructor(opts: Nfsv4ConnectionOpts);
protected onData(data: Uint8Array): void;
protected onRpcMessage(msg: RpcMessage): void;
protected onRpcCallMessage(procedure: RpcCallMessage): void;
private closeWithError;
close(): void;
private __uncorkTimer;
write(buf: Uint8Array): void;
send(): void;
}
@@ -0,0 +1,160 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Nfsv4Connection = void 0;
const tslib_1 = require("tslib");
const Reader_1 = require("@jsonjoy.com/buffers/lib/Reader");
const Nfsv4Decoder_1 = require("../Nfsv4Decoder");
const Nfsv4FullEncoder_1 = require("../Nfsv4FullEncoder");
const rm_1 = require("../../../rm");
const rpc_1 = require("../../../rpc");
const msg = tslib_1.__importStar(require("../messages"));
const constants_1 = require("../constants");
const Nfsv4CompoundProcCtx_1 = require("./Nfsv4CompoundProcCtx");
const EMPTY_AUTH = new rpc_1.RpcOpaqueAuth(0, constants_1.EMPTY_READER);
class Nfsv4Connection {
constructor(opts) {
this.closed = false;
this.maxIncomingMessage = 2 * 1024 * 1024;
this.maxBackpressure = 2 * 1024 * 1024;
this.lastXid = 0;
this.__uncorkTimer = null;
this.debug = !!opts.debug;
this.logger = opts.logger || console;
const duplex = (this.duplex = opts.duplex);
this.ops = opts.ops;
this.rmDecoder = new rm_1.RmRecordDecoder();
this.rpcDecoder = new rpc_1.RpcMessageDecoder();
this.nfsDecoder = new Nfsv4Decoder_1.Nfsv4Decoder();
const nfsEncoder = (this.nfsEncoder = new Nfsv4FullEncoder_1.Nfsv4FullEncoder());
this.writer = nfsEncoder.writer;
this.rmEncoder = nfsEncoder.rmEncoder;
this.rpcEncoder = nfsEncoder.rpcEncoder;
duplex.on('data', this.onData.bind(this));
duplex.on('timeout', () => this.close());
duplex.on('close', (hadError) => {
this.close();
});
duplex.on('error', (err) => {
this.logger.error('SOCKET ERROR:', err);
this.close();
});
}
onData(data) {
const { rmDecoder, rpcDecoder } = this;
rmDecoder.push(data);
let record = rmDecoder.readRecord();
while (record) {
if (record.size()) {
const rpcMessage = rpcDecoder.decodeMessage(record);
if (rpcMessage)
this.onRpcMessage(rpcMessage);
else {
this.close();
return;
}
}
record = rmDecoder.readRecord();
}
}
onRpcMessage(msg) {
if (msg instanceof rpc_1.RpcCallMessage) {
this.lastXid = msg.xid;
this.onRpcCallMessage(msg);
}
else if (msg instanceof rpc_1.RpcAcceptedReplyMessage) {
throw new Error('Not implemented RpcAcceptedReplyMessage');
}
else if (msg instanceof rpc_1.RpcRejectedReplyMessage) {
throw new Error('Not implemented RpcRejectedReplyMessage');
}
}
onRpcCallMessage(procedure) {
const { debug, logger, writer, rmEncoder } = this;
const { xid, proc } = procedure;
switch (proc) {
case 1: {
if (debug)
logger.log(`\n<COMPOUND{${xid}}>`);
if (!(procedure.params instanceof Reader_1.Reader))
return;
const compound = this.nfsDecoder.decodeCompoundRequest(procedure.params);
if (compound instanceof msg.Nfsv4CompoundRequest) {
new Nfsv4CompoundProcCtx_1.Nfsv4CompoundProcCtx(this, compound)
.exec()
.then((procResponse) => {
if (debug)
logger.log(`</COMPOUND{${xid}}>`);
this.nfsEncoder.writeAcceptedCompoundReply(xid, EMPTY_AUTH, procResponse);
this.write(writer.flush());
})
.catch((err) => {
logger.error('NFS COMPOUND error:', xid, err);
this.nfsEncoder.writeRejectedReply(xid, 10006);
});
}
else
this.closeWithError(4);
break;
}
case 0: {
if (debug)
logger.log('NULL', procedure);
const state = rmEncoder.startRecord();
this.rpcEncoder.writeAcceptedReply(xid, EMPTY_AUTH, 0);
rmEncoder.endRecord(state);
this.write(writer.flush());
break;
}
default: {
if (debug)
logger.error(`Unknown procedure: ${proc}`);
}
}
}
closeWithError(error) {
if (this.debug)
this.logger.log(`Closing with error: RpcAcceptStat = ${error}, xid = ${this.lastXid}`);
const xid = this.lastXid;
if (xid) {
const state = this.rmEncoder.startRecord();
const verify = new rpc_1.RpcOpaqueAuth(0, constants_1.EMPTY_READER);
this.rpcEncoder.writeAcceptedReply(xid, verify, error);
this.rmEncoder.endRecord(state);
const bin = this.writer.flush();
this.duplex.write(bin);
}
this.close();
}
close() {
if (this.closed)
return;
this.closed = true;
clearImmediate(this.__uncorkTimer);
this.__uncorkTimer = null;
const duplex = this.duplex;
duplex.removeAllListeners();
if (!duplex.destroyed)
duplex.destroy();
}
write(buf) {
if (this.closed)
return;
const duplex = this.duplex;
if (duplex.writableLength > this.maxBackpressure) {
this.closeWithError(5);
return;
}
const __uncorkTimer = this.__uncorkTimer;
if (!__uncorkTimer)
duplex.cork();
duplex.write(buf);
if (!__uncorkTimer)
this.__uncorkTimer = setImmediate(() => {
this.__uncorkTimer = null;
duplex.uncork();
});
}
send() { }
}
exports.Nfsv4Connection = Nfsv4Connection;
//# sourceMappingURL=Nfsv4Connection.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,26 @@
/// <reference types="node" />
import * as net from 'net';
import { Logger } from './types';
import { Nfsv4Operations } from './operations/Nfsv4Operations';
export interface Nfsv4TcpServerOpts {
ops: Nfsv4Operations;
port?: number;
host?: string;
debug?: boolean;
logger?: Logger;
onError?: (err: Error) => void;
stopOnSigint?: boolean;
}
export declare class Nfsv4TcpServer {
static start(opts: Nfsv4TcpServerOpts): void;
readonly server: net.Server;
port: number;
host: string;
debug: boolean;
logger: Logger;
private sigintHandler?;
constructor(opts: Nfsv4TcpServerOpts);
private cleanup;
stop(): Promise<void>;
start(port?: number, host?: string): Promise<void>;
}
@@ -0,0 +1,91 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Nfsv4TcpServer = void 0;
const tslib_1 = require("tslib");
const net = tslib_1.__importStar(require("net"));
const Nfsv4Connection_1 = require("./Nfsv4Connection");
const PORT = Number(process.env.NFS_PORT) || Number(process.env.PORT) || 2049;
const HOST = process.env.NFS_HOST
? String(process.env.NFS_HOST)
: process.env.HOST
? String(process.env.HOST)
: '127.0.0.1';
class Nfsv4TcpServer {
static start(opts) {
const server = new Nfsv4TcpServer(opts);
server.start().catch(console.error);
}
constructor(opts) {
this.port = PORT;
this.host = HOST;
this.debug = false;
this.port = opts.port ?? PORT;
this.host = opts.host ?? HOST;
this.debug = opts.debug ?? false;
this.logger = opts.logger ?? console;
const ops = opts.ops;
const server = (this.server = new net.Server());
server.on('connection', (socket) => {
if (this.debug)
this.logger.log('New connection from', socket.remoteAddress, 'port', socket.remotePort);
new Nfsv4Connection_1.Nfsv4Connection({
duplex: socket,
ops,
debug: this.debug,
logger: this.logger,
});
});
server.on('error', opts.onError ??
((err) => {
if (this.debug)
this.logger.error('Server error:', err.message);
process.exit(1);
}));
if (opts.stopOnSigint ?? true) {
this.sigintHandler = () => {
if (this.debug)
this.logger.log('\nShutting down NFSv4 server...');
this.cleanup();
process.exit(0);
};
process.on('SIGINT', this.sigintHandler);
}
}
cleanup() {
if (this.sigintHandler) {
process.off('SIGINT', this.sigintHandler);
this.sigintHandler = undefined;
}
this.server.close((err) => {
if (this.debug && err)
this.logger.error('Error closing server:', err);
});
}
stop() {
return new Promise((resolve) => {
this.cleanup();
this.server.close(() => {
if (this.debug)
this.logger.log('NFSv4 server closed');
resolve();
});
});
}
start(port = this.port, host = this.host) {
if (this.debug)
this.logger.log(`Starting NFSv4 TCP server on ${host}:${port}...`);
return new Promise((resolve, reject) => {
const onError = (err) => reject(err);
const server = this.server;
server.on('error', onError);
server.listen(port, host, () => {
if (this.debug)
this.logger.log(`NFSv4 TCP server listening on ${host}:${port}`);
server.off('error', onError);
resolve();
});
});
}
}
exports.Nfsv4TcpServer = Nfsv4TcpServer;
//# sourceMappingURL=Nfsv4TcpServer.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Nfsv4TcpServer.js","sourceRoot":"","sources":["../../../../src/nfs/v4/server/Nfsv4TcpServer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
import type * as struct from '../../structs';
export declare class ByteRangeLock {
readonly stateid: struct.Nfsv4Stateid;
readonly path: string;
readonly locktype: number;
readonly offset: bigint;
readonly length: bigint;
readonly lockOwnerKey: string;
constructor(stateid: struct.Nfsv4Stateid, path: string, locktype: number, offset: bigint, length: bigint, lockOwnerKey: string);
overlaps(offset: bigint, length: bigint): boolean;
}
@@ -0,0 +1,21 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ByteRangeLock = void 0;
class ByteRangeLock {
constructor(stateid, path, locktype, offset, length, lockOwnerKey) {
this.stateid = stateid;
this.path = path;
this.locktype = locktype;
this.offset = offset;
this.length = length;
this.lockOwnerKey = lockOwnerKey;
}
overlaps(offset, length) {
const MAX_UINT64 = BigInt('0xFFFFFFFFFFFFFFFF');
const thisEnd = this.length === MAX_UINT64 ? MAX_UINT64 : this.offset + this.length;
const otherEnd = length === MAX_UINT64 ? MAX_UINT64 : offset + length;
return this.offset < otherEnd && offset < thisEnd;
}
}
exports.ByteRangeLock = ByteRangeLock;
//# sourceMappingURL=ByteRangeLock.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ByteRangeLock.js","sourceRoot":"","sources":["../../../../../src/nfs/v4/server/operations/ByteRangeLock.ts"],"names":[],"mappings":";;;AAMA,MAAa,aAAa;IACxB,YAKkB,OAA4B,EAM5B,IAAY,EAOZ,QAAgB,EAMhB,MAAc,EAMd,MAAc,EAOd,YAAoB;QAhCpB,YAAO,GAAP,OAAO,CAAqB;QAM5B,SAAI,GAAJ,IAAI,CAAQ;QAOZ,aAAQ,GAAR,QAAQ,CAAQ;QAMhB,WAAM,GAAN,MAAM,CAAQ;QAMd,WAAM,GAAN,MAAM,CAAQ;QAOd,iBAAY,GAAZ,YAAY,CAAQ;IACnC,CAAC;IAQG,QAAQ,CAAC,MAAc,EAAE,MAAc;QAC5C,MAAM,UAAU,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QACpF,MAAM,QAAQ,GAAG,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC;QACtE,OAAO,IAAI,CAAC,MAAM,GAAG,QAAQ,IAAI,MAAM,GAAG,OAAO,CAAC;IACpD,CAAC;CACF;AArDD,sCAqDC"}
@@ -0,0 +1,13 @@
import type * as msg from '../../messages';
import type * as struct from '../../structs';
export declare class ClientRecord {
readonly principal: string;
readonly verifier: Uint8Array;
readonly clientIdString: Uint8Array;
readonly callback: struct.Nfsv4CbClient;
readonly callbackIdent: number;
readonly setclientidConfirm: Uint8Array;
cache: msg.Nfsv4SetclientidResponse | undefined;
lastRenew: number;
constructor(principal: string, verifier: Uint8Array, clientIdString: Uint8Array, callback: struct.Nfsv4CbClient, callbackIdent: number, setclientidConfirm: Uint8Array, cache?: msg.Nfsv4SetclientidResponse | undefined, lastRenew?: number);
}
@@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ClientRecord = void 0;
class ClientRecord {
constructor(principal, verifier, clientIdString, callback, callbackIdent, setclientidConfirm, cache = undefined, lastRenew = Date.now()) {
this.principal = principal;
this.verifier = verifier;
this.clientIdString = clientIdString;
this.callback = callback;
this.callbackIdent = callbackIdent;
this.setclientidConfirm = setclientidConfirm;
this.cache = cache;
this.lastRenew = lastRenew;
}
}
exports.ClientRecord = ClientRecord;
//# sourceMappingURL=ClientRecord.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ClientRecord.js","sourceRoot":"","sources":["../../../../../src/nfs/v4/server/operations/ClientRecord.ts"],"names":[],"mappings":";;;AAIA,MAAa,YAAY;IACvB,YAIkB,SAAiB,EAQjB,QAAoB,EAOpB,cAA0B,EAO1B,QAA8B,EAO9B,aAAqB,EAWrB,kBAA8B,EAQvC,QAAkD,SAAS,EAO3D,YAAoB,IAAI,CAAC,GAAG,EAAE;QAvDrB,cAAS,GAAT,SAAS,CAAQ;QAQjB,aAAQ,GAAR,QAAQ,CAAY;QAOpB,mBAAc,GAAd,cAAc,CAAY;QAO1B,aAAQ,GAAR,QAAQ,CAAsB;QAO9B,kBAAa,GAAb,aAAa,CAAQ;QAWrB,uBAAkB,GAAlB,kBAAkB,CAAY;QAQvC,UAAK,GAAL,KAAK,CAAsD;QAO3D,cAAS,GAAT,SAAS,CAAqB;IACpC,CAAC;CACL;AA9DD,oCA8DC"}
@@ -0,0 +1,9 @@
export declare class FilesystemStats {
readonly spaceAvail: bigint;
readonly spaceFree: bigint;
readonly spaceTotal: bigint;
readonly filesAvail: bigint;
readonly filesFree: bigint;
readonly filesTotal: bigint;
constructor(spaceAvail: bigint, spaceFree: bigint, spaceTotal: bigint, filesAvail: bigint, filesFree: bigint, filesTotal: bigint);
}
@@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FilesystemStats = void 0;
class FilesystemStats {
constructor(spaceAvail, spaceFree, spaceTotal, filesAvail, filesFree, filesTotal) {
this.spaceAvail = spaceAvail;
this.spaceFree = spaceFree;
this.spaceTotal = spaceTotal;
this.filesAvail = filesAvail;
this.filesFree = filesFree;
this.filesTotal = filesTotal;
}
}
exports.FilesystemStats = FilesystemStats;
//# sourceMappingURL=FilesystemStats.js.map
@@ -0,0 +1 @@
{"version":3,"file":"FilesystemStats.js","sourceRoot":"","sources":["../../../../../src/nfs/v4/server/operations/FilesystemStats.ts"],"names":[],"mappings":";;;AAGA,MAAa,eAAe;IAC1B,YAEkB,UAAkB,EAElB,SAAiB,EAEjB,UAAkB,EAElB,UAAkB,EAElB,SAAiB,EAEjB,UAAkB;QAVlB,eAAU,GAAV,UAAU,CAAQ;QAElB,cAAS,GAAT,SAAS,CAAQ;QAEjB,eAAU,GAAV,UAAU,CAAQ;QAElB,eAAU,GAAV,UAAU,CAAQ;QAElB,cAAS,GAAT,SAAS,CAAQ;QAEjB,eAAU,GAAV,UAAU,CAAQ;IACjC,CAAC;CACL;AAfD,0CAeC"}
@@ -0,0 +1,9 @@
export declare class LockOwnerState {
readonly clientid: bigint;
readonly owner: Uint8Array;
seqid: number;
readonly locks: Set<string>;
lastResponse?: any;
lastRequestKey?: string | undefined;
constructor(clientid: bigint, owner: Uint8Array, seqid: number, locks?: Set<string>, lastResponse?: any, lastRequestKey?: string | undefined);
}
@@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LockOwnerState = void 0;
class LockOwnerState {
constructor(clientid, owner, seqid, locks = new Set(), lastResponse, lastRequestKey) {
this.clientid = clientid;
this.owner = owner;
this.seqid = seqid;
this.locks = locks;
this.lastResponse = lastResponse;
this.lastRequestKey = lastRequestKey;
}
}
exports.LockOwnerState = LockOwnerState;
//# sourceMappingURL=LockOwnerState.js.map
@@ -0,0 +1 @@
{"version":3,"file":"LockOwnerState.js","sourceRoot":"","sources":["../../../../../src/nfs/v4/server/operations/LockOwnerState.ts"],"names":[],"mappings":";;;AAKA,MAAa,cAAc;IACzB,YAKkB,QAAgB,EAOhB,KAAiB,EAQ1B,KAAa,EAOJ,QAAqB,IAAI,GAAG,EAAE,EAQvC,YAAkB,EAOlB,cAAuB;QArCd,aAAQ,GAAR,QAAQ,CAAQ;QAOhB,UAAK,GAAL,KAAK,CAAY;QAQ1B,UAAK,GAAL,KAAK,CAAQ;QAOJ,UAAK,GAAL,KAAK,CAAyB;QAQvC,iBAAY,GAAZ,YAAY,CAAM;QAOlB,mBAAc,GAAd,cAAc,CAAS;IAC7B,CAAC;CACL;AA7CD,wCA6CC"}
@@ -0,0 +1,10 @@
import * as struct from '../../structs';
export declare class LockStateid {
readonly other: Uint8Array;
seqid: number;
readonly lockOwnerKey: string;
readonly path: string;
constructor(other: Uint8Array, seqid: number, lockOwnerKey: string, path: string);
toStateid(): struct.Nfsv4Stateid;
incrementAndGetStateid(): struct.Nfsv4Stateid;
}
@@ -0,0 +1,22 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LockStateid = void 0;
const tslib_1 = require("tslib");
const struct = tslib_1.__importStar(require("../../structs"));
class LockStateid {
constructor(other, seqid, lockOwnerKey, path) {
this.other = other;
this.seqid = seqid;
this.lockOwnerKey = lockOwnerKey;
this.path = path;
}
toStateid() {
return new struct.Nfsv4Stateid(this.seqid, this.other);
}
incrementAndGetStateid() {
this.seqid = this.seqid === 0xffffffff ? 1 : this.seqid + 1;
return this.toStateid();
}
}
exports.LockStateid = LockStateid;
//# sourceMappingURL=LockStateid.js.map
@@ -0,0 +1 @@
{"version":3,"file":"LockStateid.js","sourceRoot":"","sources":["../../../../../src/nfs/v4/server/operations/LockStateid.ts"],"names":[],"mappings":";;;;AAAA,8DAAwC;AASxC,MAAa,WAAW;IACtB,YAMkB,KAAiB,EAO1B,KAAa,EAMJ,YAAoB,EAMpB,IAAY;QAnBZ,UAAK,GAAL,KAAK,CAAY;QAO1B,UAAK,GAAL,KAAK,CAAQ;QAMJ,iBAAY,GAAZ,YAAY,CAAQ;QAMpB,SAAI,GAAJ,IAAI,CAAQ;IAC3B,CAAC;IAKJ,SAAS;QACP,OAAO,IAAI,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IACzD,CAAC;IAMD,sBAAsB;QACpB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QAC5D,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC;IAC1B,CAAC;CACF;AA5CD,kCA4CC"}
@@ -0,0 +1,44 @@
import * as msg from '../../messages';
import type { Nfsv4CompoundProcCtx } from '../Nfsv4CompoundProcCtx';
export type Nfsv4OperationCtx = Pick<Nfsv4CompoundProcCtx, 'cfh' | 'sfh' | 'req' | 'getPrincipal' | 'connection'>;
export type Nfsv4OperationFn<Req extends msg.Nfsv4Request, Res extends msg.Nfsv4Response> = (request: Req, ctx: Nfsv4OperationCtx) => Promise<Res>;
export interface Nfsv4Operations {
ACCESS: Nfsv4OperationFn<msg.Nfsv4AccessRequest, msg.Nfsv4AccessResponse>;
CLOSE: Nfsv4OperationFn<msg.Nfsv4CloseRequest, msg.Nfsv4CloseResponse>;
COMMIT: Nfsv4OperationFn<msg.Nfsv4CommitRequest, msg.Nfsv4CommitResponse>;
CREATE: Nfsv4OperationFn<msg.Nfsv4CreateRequest, msg.Nfsv4CreateResponse>;
DELEGPURGE: Nfsv4OperationFn<msg.Nfsv4DelegpurgeRequest, msg.Nfsv4DelegpurgeResponse>;
DELEGRETURN: Nfsv4OperationFn<msg.Nfsv4DelegreturnRequest, msg.Nfsv4DelegreturnResponse>;
GETATTR: Nfsv4OperationFn<msg.Nfsv4GetattrRequest, msg.Nfsv4GetattrResponse>;
GETFH: Nfsv4OperationFn<msg.Nfsv4GetfhRequest, msg.Nfsv4GetfhResponse>;
LINK: Nfsv4OperationFn<msg.Nfsv4LinkRequest, msg.Nfsv4LinkResponse>;
LOCK: Nfsv4OperationFn<msg.Nfsv4LockRequest, msg.Nfsv4LockResponse>;
LOCKT: Nfsv4OperationFn<msg.Nfsv4LocktRequest, msg.Nfsv4LocktResponse>;
LOCKU: Nfsv4OperationFn<msg.Nfsv4LockuRequest, msg.Nfsv4LockuResponse>;
LOOKUP: Nfsv4OperationFn<msg.Nfsv4LookupRequest, msg.Nfsv4LookupResponse>;
LOOKUPP: Nfsv4OperationFn<msg.Nfsv4LookuppRequest, msg.Nfsv4LookuppResponse>;
NVERIFY: Nfsv4OperationFn<msg.Nfsv4NverifyRequest, msg.Nfsv4NverifyResponse>;
OPEN: Nfsv4OperationFn<msg.Nfsv4OpenRequest, msg.Nfsv4OpenResponse>;
OPENATTR: Nfsv4OperationFn<msg.Nfsv4OpenattrRequest, msg.Nfsv4OpenattrResponse>;
OPEN_CONFIRM: Nfsv4OperationFn<msg.Nfsv4OpenConfirmRequest, msg.Nfsv4OpenConfirmResponse>;
OPEN_DOWNGRADE: Nfsv4OperationFn<msg.Nfsv4OpenDowngradeRequest, msg.Nfsv4OpenDowngradeResponse>;
PUTFH: Nfsv4OperationFn<msg.Nfsv4PutfhRequest, msg.Nfsv4PutfhResponse>;
PUTPUBFH: Nfsv4OperationFn<msg.Nfsv4PutpubfhRequest, msg.Nfsv4PutpubfhResponse>;
PUTROOTFH: Nfsv4OperationFn<msg.Nfsv4PutrootfhRequest, msg.Nfsv4PutrootfhResponse>;
READ: Nfsv4OperationFn<msg.Nfsv4ReadRequest, msg.Nfsv4ReadResponse>;
READDIR: Nfsv4OperationFn<msg.Nfsv4ReaddirRequest, msg.Nfsv4ReaddirResponse>;
READLINK: Nfsv4OperationFn<msg.Nfsv4ReadlinkRequest, msg.Nfsv4ReadlinkResponse>;
REMOVE: Nfsv4OperationFn<msg.Nfsv4RemoveRequest, msg.Nfsv4RemoveResponse>;
RENAME: Nfsv4OperationFn<msg.Nfsv4RenameRequest, msg.Nfsv4RenameResponse>;
RENEW: Nfsv4OperationFn<msg.Nfsv4RenewRequest, msg.Nfsv4RenewResponse>;
RESTOREFH: Nfsv4OperationFn<msg.Nfsv4RestorefhRequest, msg.Nfsv4RestorefhResponse>;
SAVEFH: Nfsv4OperationFn<msg.Nfsv4SavefhRequest, msg.Nfsv4SavefhResponse>;
SECINFO: Nfsv4OperationFn<msg.Nfsv4SecinfoRequest, msg.Nfsv4SecinfoResponse>;
SETATTR: Nfsv4OperationFn<msg.Nfsv4SetattrRequest, msg.Nfsv4SetattrResponse>;
SETCLIENTID: Nfsv4OperationFn<msg.Nfsv4SetclientidRequest, msg.Nfsv4SetclientidResponse>;
SETCLIENTID_CONFIRM: Nfsv4OperationFn<msg.Nfsv4SetclientidConfirmRequest, msg.Nfsv4SetclientidConfirmResponse>;
VERIFY: Nfsv4OperationFn<msg.Nfsv4VerifyRequest, msg.Nfsv4VerifyResponse>;
WRITE: Nfsv4OperationFn<msg.Nfsv4WriteRequest, msg.Nfsv4WriteResponse>;
RELEASE_LOCKOWNER: Nfsv4OperationFn<msg.Nfsv4ReleaseLockOwnerRequest, msg.Nfsv4ReleaseLockOwnerResponse>;
ILLEGAL: Nfsv4OperationFn<msg.Nfsv4IllegalRequest, msg.Nfsv4IllegalResponse>;
}
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=Nfsv4Operations.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Nfsv4Operations.js","sourceRoot":"","sources":["../../../../../src/nfs/v4/server/operations/Nfsv4Operations.ts"],"names":[],"mappings":""}
@@ -0,0 +1,42 @@
import * as msg from '../../messages';
import { Nfsv4OperationCtx, Nfsv4Operations } from './Nfsv4Operations';
export declare class Nfsv4OperationsNotImpl implements Nfsv4Operations {
ACCESS(request: msg.Nfsv4AccessRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4AccessResponse>;
CLOSE(request: msg.Nfsv4CloseRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4CloseResponse>;
COMMIT(request: msg.Nfsv4CommitRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4CommitResponse>;
CREATE(request: msg.Nfsv4CreateRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4CreateResponse>;
DELEGPURGE(request: msg.Nfsv4DelegpurgeRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4DelegpurgeResponse>;
DELEGRETURN(request: msg.Nfsv4DelegreturnRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4DelegreturnResponse>;
GETATTR(request: msg.Nfsv4GetattrRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4GetattrResponse>;
GETFH(request: msg.Nfsv4GetfhRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4GetfhResponse>;
LINK(request: msg.Nfsv4LinkRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4LinkResponse>;
LOCK(request: msg.Nfsv4LockRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4LockResponse>;
LOCKT(request: msg.Nfsv4LocktRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4LocktResponse>;
LOCKU(request: msg.Nfsv4LockuRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4LockuResponse>;
LOOKUP(request: msg.Nfsv4LookupRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4LookupResponse>;
LOOKUPP(request: msg.Nfsv4LookuppRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4LookuppResponse>;
NVERIFY(request: msg.Nfsv4NverifyRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4NverifyResponse>;
OPEN(request: msg.Nfsv4OpenRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4OpenResponse>;
OPENATTR(request: msg.Nfsv4OpenattrRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4OpenattrResponse>;
OPEN_CONFIRM(request: msg.Nfsv4OpenConfirmRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4OpenConfirmResponse>;
OPEN_DOWNGRADE(request: msg.Nfsv4OpenDowngradeRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4OpenDowngradeResponse>;
PUTFH(request: msg.Nfsv4PutfhRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4PutfhResponse>;
PUTPUBFH(request: msg.Nfsv4PutpubfhRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4PutpubfhResponse>;
PUTROOTFH(request: msg.Nfsv4PutrootfhRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4PutrootfhResponse>;
READ(request: msg.Nfsv4ReadRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4ReadResponse>;
READDIR(request: msg.Nfsv4ReaddirRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4ReaddirResponse>;
READLINK(request: msg.Nfsv4ReadlinkRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4ReadlinkResponse>;
REMOVE(request: msg.Nfsv4RemoveRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4RemoveResponse>;
RENAME(request: msg.Nfsv4RenameRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4RenameResponse>;
RENEW(request: msg.Nfsv4RenewRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4RenewResponse>;
RESTOREFH(request: msg.Nfsv4RestorefhRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4RestorefhResponse>;
SAVEFH(request: msg.Nfsv4SavefhRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4SavefhResponse>;
SECINFO(request: msg.Nfsv4SecinfoRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4SecinfoResponse>;
SETATTR(request: msg.Nfsv4SetattrRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4SetattrResponse>;
SETCLIENTID(request: msg.Nfsv4SetclientidRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4SetclientidResponse>;
SETCLIENTID_CONFIRM(request: msg.Nfsv4SetclientidConfirmRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4SetclientidConfirmResponse>;
VERIFY(request: msg.Nfsv4VerifyRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4VerifyResponse>;
WRITE(request: msg.Nfsv4WriteRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4WriteResponse>;
RELEASE_LOCKOWNER(request: msg.Nfsv4ReleaseLockOwnerRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4ReleaseLockOwnerResponse>;
ILLEGAL(request: msg.Nfsv4IllegalRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4IllegalResponse>;
}
@@ -0,0 +1,159 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Nfsv4OperationsNotImpl = void 0;
class Nfsv4OperationsNotImpl {
async ACCESS(request, ctx) {
ctx.connection.logger.log('ACCESS', request);
throw new Error('Not implemented');
}
async CLOSE(request, ctx) {
ctx.connection.logger.log('CLOSE', request);
throw new Error('Not implemented');
}
async COMMIT(request, ctx) {
ctx.connection.logger.log('COMMIT', request);
throw new Error('Not implemented');
}
async CREATE(request, ctx) {
ctx.connection.logger.log('CREATE', request);
throw new Error('Not implemented');
}
async DELEGPURGE(request, ctx) {
ctx.connection.logger.log('DELEGPURGE', request);
throw new Error('Not implemented');
}
async DELEGRETURN(request, ctx) {
ctx.connection.logger.log('DELEGRETURN', request);
throw new Error('Not implemented');
}
async GETATTR(request, ctx) {
ctx.connection.logger.log('GETATTR', request);
throw new Error('Not implemented');
}
async GETFH(request, ctx) {
ctx.connection.logger.log('GETFH', request);
throw new Error('Not implemented');
}
async LINK(request, ctx) {
ctx.connection.logger.log('LINK', request);
throw new Error('Not implemented');
}
async LOCK(request, ctx) {
ctx.connection.logger.log('LOCK', request);
throw new Error('Not implemented');
}
async LOCKT(request, ctx) {
ctx.connection.logger.log('LOCKT', request);
throw new Error('Not implemented');
}
async LOCKU(request, ctx) {
ctx.connection.logger.log('LOCKU', request);
throw new Error('Not implemented');
}
async LOOKUP(request, ctx) {
ctx.connection.logger.log('LOOKUP', request);
throw new Error('Not implemented');
}
async LOOKUPP(request, ctx) {
ctx.connection.logger.log('LOOKUPP', request);
throw new Error('Not implemented');
}
async NVERIFY(request, ctx) {
ctx.connection.logger.log('NVERIFY', request);
throw new Error('Not implemented');
}
async OPEN(request, ctx) {
ctx.connection.logger.log('OPEN', request);
throw new Error('Not implemented');
}
async OPENATTR(request, ctx) {
ctx.connection.logger.log('OPENATTR', request);
throw new Error('Not implemented');
}
async OPEN_CONFIRM(request, ctx) {
ctx.connection.logger.log('OPEN_CONFIRM', request);
throw new Error('Not implemented');
}
async OPEN_DOWNGRADE(request, ctx) {
ctx.connection.logger.log('OPEN_DOWNGRADE', request);
throw new Error('Not implemented');
}
async PUTFH(request, ctx) {
ctx.connection.logger.log('PUTFH', request);
throw new Error('Not implemented');
}
async PUTPUBFH(request, ctx) {
ctx.connection.logger.log('PUTPUBFH', request);
throw new Error('Not implemented');
}
async PUTROOTFH(request, ctx) {
ctx.connection.logger.log('PUTROOTFH', request);
throw new Error('Not implemented');
}
async READ(request, ctx) {
ctx.connection.logger.log('READ', request);
throw new Error('Not implemented');
}
async READDIR(request, ctx) {
ctx.connection.logger.log('READDIR', request);
throw new Error('Not implemented');
}
async READLINK(request, ctx) {
ctx.connection.logger.log('READLINK', request);
throw new Error('Not implemented');
}
async REMOVE(request, ctx) {
ctx.connection.logger.log('REMOVE', request);
throw new Error('Not implemented');
}
async RENAME(request, ctx) {
ctx.connection.logger.log('RENAME', request);
throw new Error('Not implemented');
}
async RENEW(request, ctx) {
ctx.connection.logger.log('RENEW', request);
throw new Error('Not implemented');
}
async RESTOREFH(request, ctx) {
ctx.connection.logger.log('RESTOREFH', request);
throw new Error('Not implemented');
}
async SAVEFH(request, ctx) {
ctx.connection.logger.log('SAVEFH', request);
throw new Error('Not implemented');
}
async SECINFO(request, ctx) {
ctx.connection.logger.log('SECINFO', request);
throw new Error('Not implemented');
}
async SETATTR(request, ctx) {
ctx.connection.logger.log('SETATTR', request);
throw new Error('Not implemented');
}
async SETCLIENTID(request, ctx) {
ctx.connection.logger.log('SETCLIENTID', request);
throw new Error('Not implemented');
}
async SETCLIENTID_CONFIRM(request, ctx) {
ctx.connection.logger.log('SETCLIENTID_CONFIRM', request);
throw new Error('Not implemented');
}
async VERIFY(request, ctx) {
ctx.connection.logger.log('VERIFY', request);
throw new Error('Not implemented');
}
async WRITE(request, ctx) {
ctx.connection.logger.log('WRITE', request);
throw new Error('Not implemented');
}
async RELEASE_LOCKOWNER(request, ctx) {
ctx.connection.logger.log('RELEASE_LOCKOWNER', request);
throw new Error('Not implemented');
}
async ILLEGAL(request, ctx) {
ctx.connection.logger.log('ILLEGAL', request);
throw new Error('Not implemented');
}
}
exports.Nfsv4OperationsNotImpl = Nfsv4OperationsNotImpl;
//# sourceMappingURL=Nfsv4OperationsNotImpl.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,14 @@
/// <reference types="node" />
import type * as struct from '../../structs';
import type { FileHandle } from 'node:fs/promises';
export declare class OpenFileState {
readonly stateid: struct.Nfsv4Stateid;
readonly path: string;
readonly fd: FileHandle;
shareAccess: number;
shareDeny: number;
readonly openOwnerKey: string;
seqid: number;
confirmed: boolean;
constructor(stateid: struct.Nfsv4Stateid, path: string, fd: FileHandle, shareAccess: number, shareDeny: number, openOwnerKey: string, seqid: number, confirmed: boolean);
}
@@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OpenFileState = void 0;
class OpenFileState {
constructor(stateid, path, fd, shareAccess, shareDeny, openOwnerKey, seqid, confirmed) {
this.stateid = stateid;
this.path = path;
this.fd = fd;
this.shareAccess = shareAccess;
this.shareDeny = shareDeny;
this.openOwnerKey = openOwnerKey;
this.seqid = seqid;
this.confirmed = confirmed;
}
}
exports.OpenFileState = OpenFileState;
//# sourceMappingURL=OpenFileState.js.map
@@ -0,0 +1 @@
{"version":3,"file":"OpenFileState.js","sourceRoot":"","sources":["../../../../../src/nfs/v4/server/operations/OpenFileState.ts"],"names":[],"mappings":";;;AAQA,MAAa,aAAa;IACxB,YAMkB,OAA4B,EAM5B,IAAY,EAMZ,EAAc,EAOvB,WAAmB,EAOnB,SAAiB,EAOR,YAAoB,EAO7B,KAAa,EAOb,SAAkB;QA/CT,YAAO,GAAP,OAAO,CAAqB;QAM5B,SAAI,GAAJ,IAAI,CAAQ;QAMZ,OAAE,GAAF,EAAE,CAAY;QAOvB,gBAAW,GAAX,WAAW,CAAQ;QAOnB,cAAS,GAAT,SAAS,CAAQ;QAOR,iBAAY,GAAZ,YAAY,CAAQ;QAO7B,UAAK,GAAL,KAAK,CAAQ;QAOb,cAAS,GAAT,SAAS,CAAS;IACxB,CAAC;CACL;AAxDD,sCAwDC"}
@@ -0,0 +1,9 @@
export declare class OpenOwnerState {
readonly clientid: bigint;
readonly owner: Uint8Array;
seqid: number;
readonly opens: Set<string>;
lastResponse?: any;
lastRequestKey?: string | undefined;
constructor(clientid: bigint, owner: Uint8Array, seqid: number, opens?: Set<string>, lastResponse?: any, lastRequestKey?: string | undefined);
}
@@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OpenOwnerState = void 0;
class OpenOwnerState {
constructor(clientid, owner, seqid, opens = new Set(), lastResponse, lastRequestKey) {
this.clientid = clientid;
this.owner = owner;
this.seqid = seqid;
this.opens = opens;
this.lastResponse = lastResponse;
this.lastRequestKey = lastRequestKey;
}
}
exports.OpenOwnerState = OpenOwnerState;
//# sourceMappingURL=OpenOwnerState.js.map
@@ -0,0 +1 @@
{"version":3,"file":"OpenOwnerState.js","sourceRoot":"","sources":["../../../../../src/nfs/v4/server/operations/OpenOwnerState.ts"],"names":[],"mappings":";;;AAMA,MAAa,cAAc;IACzB,YAKkB,QAAgB,EAOhB,KAAiB,EAQ1B,KAAa,EAOJ,QAAqB,IAAI,GAAG,EAAE,EAQvC,YAAkB,EAOlB,cAAuB;QArCd,aAAQ,GAAR,QAAQ,CAAQ;QAOhB,UAAK,GAAL,KAAK,CAAY;QAQ1B,UAAK,GAAL,KAAK,CAAQ;QAOJ,UAAK,GAAL,KAAK,CAAyB;QAQvC,iBAAY,GAAZ,YAAY,CAAM;QAOlB,mBAAc,GAAd,cAAc,CAAS;IAC7B,CAAC;CACL;AA7CD,wCA6CC"}
@@ -0,0 +1,99 @@
/// <reference types="node" />
import { Nfsv4OperationCtx, Nfsv4Operations } from '../Nfsv4Operations';
import * as msg from '../../../messages';
import * as struct from '../../../structs';
import { ClientRecord } from '../ClientRecord';
import { OpenFileState } from '../OpenFileState';
import { OpenOwnerState } from '../OpenOwnerState';
import { LockOwnerState } from '../LockOwnerState';
import { ByteRangeLock } from '../ByteRangeLock';
import { LockStateid } from '../LockStateid';
import { FilesystemStats } from '../FilesystemStats';
import { FileHandleMapper } from './fh';
export interface Nfsv4OperationsNodeOpts {
fs: typeof import('node:fs');
dir: string;
maxClients?: number;
maxPendingClients?: number;
fsStats?: () => Promise<FilesystemStats>;
}
export declare class Nfsv4OperationsNode implements Nfsv4Operations {
protected readonly fs: typeof import('node:fs');
protected readonly promises: (typeof import('node:fs'))['promises'];
protected dir: string;
protected readonly leaseTime: number;
protected clients: Map<bigint, ClientRecord>;
protected pendingClients: Map<bigint, ClientRecord>;
protected maxClients: number;
protected maxPendingClients: number;
protected nextClientId: bigint;
protected bootStamp: number;
protected readonly fh: FileHandleMapper;
protected nextStateidSeqid: number;
protected openFiles: Map<string, OpenFileState>;
protected openOwners: Map<string, OpenOwnerState>;
protected locks: Map<string, ByteRangeLock>;
protected lockOwners: Map<string, LockOwnerState>;
protected lockStateids: Map<string, LockStateid>;
protected changeCounter: bigint;
protected fsStats: () => Promise<FilesystemStats>;
constructor(opts: Nfsv4OperationsNodeOpts);
protected defaultFsStats: () => Promise<FilesystemStats>;
protected findClientByIdString(map: Map<bigint, ClientRecord>, clientIdString: Uint8Array): [bigint, ClientRecord] | undefined;
protected enforceClientLimit(): void;
protected enforcePendingClientLimit(): void;
protected makeOpenOwnerKey(clientid: bigint, owner: Uint8Array): string;
protected validateSeqid(requestSeqid: number, ownerSeqid: number): 'valid' | 'replay' | 'invalid';
protected renewClientLease(clientid: bigint): void;
protected makeStateidKey(stateid: struct.Nfsv4Stateid): string;
protected createStateid(): struct.Nfsv4Stateid;
protected canAccessFile(path: string, shareAccess: number, shareDeny: number): boolean;
protected makeLockOwnerKey(clientid: bigint, owner: Uint8Array): string;
protected makeOpenRequestKey(ownerKey: string, currentPath: string, request: msg.Nfsv4OpenRequest): string;
protected makeLockRequestKey(lockOwnerKey: string, filePath: string, locktype: number, offset: bigint, length: bigint, seqid: number): string;
protected makeLockuRequestKey(lockOwnerKey: string, stateid: struct.Nfsv4Stateid, offset: bigint, length: bigint, seqid: number): string;
protected makeLockKey(stateid: struct.Nfsv4Stateid, offset: bigint, length: bigint): string;
protected makeLockStateidKey(lockOwnerKey: string, path: string): string;
protected getOrCreateLockStateid(lockOwnerKey: string, path: string): LockStateid;
protected findLockStateidByOther(other: Uint8Array): LockStateid | undefined;
protected hasConflictingLock(path: string, locktype: number, offset: bigint, length: bigint, ownerKey: string): boolean;
SETCLIENTID(request: msg.Nfsv4SetclientidRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4SetclientidResponse>;
SETCLIENTID_CONFIRM(request: msg.Nfsv4SetclientidConfirmRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4SetclientidConfirmResponse>;
ILLEGAL(request: msg.Nfsv4IllegalRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4IllegalResponse>;
PUTROOTFH(request: msg.Nfsv4PutrootfhRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4PutrootfhResponse>;
PUTPUBFH(request: msg.Nfsv4PutpubfhRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4PutpubfhResponse>;
PUTFH(request: msg.Nfsv4PutfhRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4PutfhResponse>;
GETFH(request: msg.Nfsv4GetfhRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4GetfhResponse>;
RESTOREFH(request: msg.Nfsv4RestorefhRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4RestorefhResponse>;
SAVEFH(request: msg.Nfsv4SavefhRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4SavefhResponse>;
private absolutePath;
LOOKUP(request: msg.Nfsv4LookupRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4LookupResponse>;
LOOKUPP(request: msg.Nfsv4LookuppRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4LookuppResponse>;
GETATTR(request: msg.Nfsv4GetattrRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4GetattrResponse>;
ACCESS(request: msg.Nfsv4AccessRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4AccessResponse>;
READDIR(request: msg.Nfsv4ReaddirRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4ReaddirResponse>;
OPEN(request: msg.Nfsv4OpenRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4OpenResponse>;
OPENATTR(request: msg.Nfsv4OpenattrRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4OpenattrResponse>;
OPEN_CONFIRM(request: msg.Nfsv4OpenConfirmRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4OpenConfirmResponse>;
OPEN_DOWNGRADE(request: msg.Nfsv4OpenDowngradeRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4OpenDowngradeResponse>;
CLOSE(request: msg.Nfsv4CloseRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4CloseResponse>;
SECINFO(request: msg.Nfsv4SecinfoRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4SecinfoResponse>;
LOCK(request: msg.Nfsv4LockRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4LockResponse>;
LOCKT(request: msg.Nfsv4LocktRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4LocktResponse>;
LOCKU(request: msg.Nfsv4LockuRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4LockuResponse>;
RELEASE_LOCKOWNER(request: msg.Nfsv4ReleaseLockOwnerRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4ReleaseLockOwnerResponse>;
RENEW(request: msg.Nfsv4RenewRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4RenewResponse>;
READ(request: msg.Nfsv4ReadRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4ReadResponse>;
READLINK(request: msg.Nfsv4ReadlinkRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4ReadlinkResponse>;
REMOVE(request: msg.Nfsv4RemoveRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4RemoveResponse>;
RENAME(request: msg.Nfsv4RenameRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4RenameResponse>;
WRITE(request: msg.Nfsv4WriteRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4WriteResponse>;
DELEGPURGE(request: msg.Nfsv4DelegpurgeRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4DelegpurgeResponse>;
DELEGRETURN(request: msg.Nfsv4DelegreturnRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4DelegreturnResponse>;
COMMIT(request: msg.Nfsv4CommitRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4CommitResponse>;
CREATE(request: msg.Nfsv4CreateRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4CreateResponse>;
LINK(request: msg.Nfsv4LinkRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4LinkResponse>;
NVERIFY(request: msg.Nfsv4NverifyRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4NverifyResponse>;
SETATTR(request: msg.Nfsv4SetattrRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4SetattrResponse>;
VERIFY(request: msg.Nfsv4VerifyRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4VerifyResponse>;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,5 @@
/// <reference types="node" />
import type { Stats } from 'node:fs';
import * as struct from '../../../structs';
import type { FilesystemStats } from '../FilesystemStats';
export declare const encodeAttrs: (requestedAttrs: struct.Nfsv4Bitmap, stats: Stats | undefined, path: string, fh?: Uint8Array, leaseTime?: number, fsStats?: FilesystemStats) => struct.Nfsv4Fattr;
@@ -0,0 +1,262 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.encodeAttrs = void 0;
const tslib_1 = require("tslib");
const Writer_1 = require("@jsonjoy.com/buffers/lib/Writer");
const XdrEncoder_1 = require("../../../../../xdr/XdrEncoder");
const struct = tslib_1.__importStar(require("../../../structs"));
const attributes_1 = require("../../../attributes");
const encodeAttrs = (requestedAttrs, stats, path, fh, leaseTime, fsStats) => {
const writer = new Writer_1.Writer(512);
const xdr = new XdrEncoder_1.XdrEncoder(writer);
const supportedMask = [];
const requested = requestedAttrs.mask;
for (let i = 0; i < requested.length; i++) {
const word = requested[i];
if (!word)
continue;
const wordIndex = i;
for (let bit = 0; bit < 32; bit++) {
if (!(word & (1 << bit)))
continue;
const attrNum = wordIndex * 32 + bit;
switch (attrNum) {
case 0: {
const implementedAttrs = [];
(0, attributes_1.setBit)(implementedAttrs, 0);
(0, attributes_1.setBit)(implementedAttrs, 1);
(0, attributes_1.setBit)(implementedAttrs, 2);
(0, attributes_1.setBit)(implementedAttrs, 3);
(0, attributes_1.setBit)(implementedAttrs, 4);
(0, attributes_1.setBit)(implementedAttrs, 5);
(0, attributes_1.setBit)(implementedAttrs, 6);
(0, attributes_1.setBit)(implementedAttrs, 7);
(0, attributes_1.setBit)(implementedAttrs, 8);
(0, attributes_1.setBit)(implementedAttrs, 9);
(0, attributes_1.setBit)(implementedAttrs, 10);
(0, attributes_1.setBit)(implementedAttrs, 11);
(0, attributes_1.setBit)(implementedAttrs, 19);
(0, attributes_1.setBit)(implementedAttrs, 20);
(0, attributes_1.setBit)(implementedAttrs, 33);
(0, attributes_1.setBit)(implementedAttrs, 35);
(0, attributes_1.setBit)(implementedAttrs, 45);
(0, attributes_1.setBit)(implementedAttrs, 42);
(0, attributes_1.setBit)(implementedAttrs, 43);
(0, attributes_1.setBit)(implementedAttrs, 44);
(0, attributes_1.setBit)(implementedAttrs, 21);
(0, attributes_1.setBit)(implementedAttrs, 22);
(0, attributes_1.setBit)(implementedAttrs, 23);
(0, attributes_1.setBit)(implementedAttrs, 47);
(0, attributes_1.setBit)(implementedAttrs, 52);
(0, attributes_1.setBit)(implementedAttrs, 53);
xdr.writeUnsignedInt(implementedAttrs.length);
for (let j = 0; j < implementedAttrs.length; j++) {
xdr.writeUnsignedInt(implementedAttrs[j]);
}
(0, attributes_1.setBit)(supportedMask, attrNum);
break;
}
case 1: {
if (!stats)
break;
let type;
if (stats.isFile())
type = 1;
else if (stats.isDirectory())
type = 2;
else if (stats.isSymbolicLink())
type = 5;
else if (stats.isBlockDevice())
type = 3;
else if (stats.isCharacterDevice())
type = 4;
else if (stats.isFIFO())
type = 7;
else if (stats.isSocket())
type = 6;
else
type = 1;
xdr.writeUnsignedInt(type);
(0, attributes_1.setBit)(supportedMask, attrNum);
break;
}
case 4: {
if (!stats)
break;
xdr.writeUnsignedHyper(BigInt(stats.size));
(0, attributes_1.setBit)(supportedMask, attrNum);
break;
}
case 20: {
if (!stats)
break;
xdr.writeUnsignedHyper(BigInt(stats.ino));
(0, attributes_1.setBit)(supportedMask, attrNum);
break;
}
case 33: {
if (!stats)
break;
xdr.writeUnsignedInt(stats.mode & 0o7777);
(0, attributes_1.setBit)(supportedMask, attrNum);
break;
}
case 35: {
if (!stats)
break;
xdr.writeUnsignedInt(stats.nlink);
(0, attributes_1.setBit)(supportedMask, attrNum);
break;
}
case 45: {
if (!stats)
break;
xdr.writeUnsignedHyper(BigInt(stats.blocks * 512));
(0, attributes_1.setBit)(supportedMask, attrNum);
break;
}
case 42: {
if (!fsStats)
break;
xdr.writeUnsignedHyper(fsStats.spaceAvail);
(0, attributes_1.setBit)(supportedMask, attrNum);
break;
}
case 43: {
if (!fsStats)
break;
xdr.writeUnsignedHyper(fsStats.spaceFree);
(0, attributes_1.setBit)(supportedMask, attrNum);
break;
}
case 44: {
if (!fsStats)
break;
xdr.writeUnsignedHyper(fsStats.spaceTotal);
(0, attributes_1.setBit)(supportedMask, attrNum);
break;
}
case 21: {
if (!fsStats)
break;
xdr.writeUnsignedHyper(fsStats.filesAvail);
(0, attributes_1.setBit)(supportedMask, attrNum);
break;
}
case 22: {
if (!fsStats)
break;
xdr.writeUnsignedHyper(fsStats.filesFree);
(0, attributes_1.setBit)(supportedMask, attrNum);
break;
}
case 23: {
if (!fsStats)
break;
xdr.writeUnsignedHyper(fsStats.filesTotal);
(0, attributes_1.setBit)(supportedMask, attrNum);
break;
}
case 47: {
if (!stats)
break;
const atime = stats.atimeMs;
const seconds = Math.floor(atime / 1000);
const nseconds = Math.floor((atime % 1000) * 1000000);
xdr.writeHyper(BigInt(seconds));
xdr.writeUnsignedInt(nseconds);
(0, attributes_1.setBit)(supportedMask, attrNum);
break;
}
case 53: {
if (!stats)
break;
const mtime = stats.mtimeMs;
const seconds = Math.floor(mtime / 1000);
const nseconds = Math.floor((mtime % 1000) * 1000000);
xdr.writeHyper(BigInt(seconds));
xdr.writeUnsignedInt(nseconds);
(0, attributes_1.setBit)(supportedMask, attrNum);
break;
}
case 52: {
if (!stats)
break;
const ctime = stats.ctimeMs;
const seconds = Math.floor(ctime / 1000);
const nseconds = Math.floor((ctime % 1000) * 1000000);
xdr.writeHyper(BigInt(seconds));
xdr.writeUnsignedInt(nseconds);
(0, attributes_1.setBit)(supportedMask, attrNum);
break;
}
case 3: {
if (!stats)
break;
const changeTime = BigInt(Math.floor(stats.mtimeMs * 1000000));
xdr.writeUnsignedHyper(changeTime);
(0, attributes_1.setBit)(supportedMask, attrNum);
break;
}
case 10: {
if (leaseTime !== undefined) {
xdr.writeUnsignedInt(leaseTime);
(0, attributes_1.setBit)(supportedMask, attrNum);
}
break;
}
case 2: {
xdr.writeUnsignedInt(2);
(0, attributes_1.setBit)(supportedMask, attrNum);
break;
}
case 5: {
xdr.writeUnsignedInt(1);
(0, attributes_1.setBit)(supportedMask, attrNum);
break;
}
case 6: {
xdr.writeUnsignedInt(1);
(0, attributes_1.setBit)(supportedMask, attrNum);
break;
}
case 7: {
xdr.writeUnsignedInt(0);
(0, attributes_1.setBit)(supportedMask, attrNum);
break;
}
case 8: {
xdr.writeUnsignedHyper(BigInt(0));
xdr.writeUnsignedHyper(BigInt(0));
(0, attributes_1.setBit)(supportedMask, attrNum);
break;
}
case 9: {
xdr.writeUnsignedInt(1);
(0, attributes_1.setBit)(supportedMask, attrNum);
break;
}
case 11: {
xdr.writeUnsignedInt(0);
(0, attributes_1.setBit)(supportedMask, attrNum);
break;
}
case 19: {
if (fh) {
xdr.writeVarlenOpaque(fh);
(0, attributes_1.setBit)(supportedMask, attrNum);
}
break;
}
default: {
if (attributes_1.SET_ONLY_ATTRS.has(attrNum))
throw 22;
}
}
}
}
const attrVals = writer.flush();
return new struct.Nfsv4Fattr(new struct.Nfsv4Bitmap(supportedMask), attrVals);
};
exports.encodeAttrs = encodeAttrs;
//# sourceMappingURL=attrs.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,28 @@
import type { Nfsv4OperationCtx } from '../Nfsv4Operations';
export declare const ROOT_FH: Uint8Array;
export declare const enum FH_TYPE {
ROOT = 0,
PATH = 1,
ID = 2
}
export declare const enum FH {
MAX_SIZE = 128
}
export declare const encodePathFh: (absolutePath: string) => Uint8Array | undefined;
export declare const decodePathFh: (fh: Uint8Array) => string | undefined;
export declare class FileHandleMapper {
protected readonly dir: string;
protected readonly stamp: number;
protected idToPath: Map<number, string>;
protected pathToId: Map<string, Uint8Array>;
protected readonly maxFhTableSize = 100000;
constructor(stamp: number, dir: string);
decode(fh: Uint8Array): string;
encode(path: string): Uint8Array;
validate(fh: Uint8Array): boolean;
currentPath(ctx: Nfsv4OperationCtx): string;
savedPath(ctx: Nfsv4OperationCtx): string;
setCfh(ctx: Nfsv4OperationCtx, path: string): void;
remove(path: string): void;
rename(oldPath: string, newPath: string): void;
}
@@ -0,0 +1,147 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FileHandleMapper = exports.decodePathFh = exports.encodePathFh = exports.ROOT_FH = void 0;
const encode_1 = require("@jsonjoy.com/buffers/lib/utf8/encode");
const decodeUtf8_1 = require("@jsonjoy.com/buffers/lib/utf8/decodeUtf8");
const node_crypto_1 = require("node:crypto");
exports.ROOT_FH = new Uint8Array([0]);
const encodePathFh = (absolutePath) => {
const utf8Length = Buffer.byteLength(absolutePath, 'utf8');
if (utf8Length + 1 > 128)
return undefined;
const u8 = new Uint8Array(1 + utf8Length);
u8[0] = 1;
(0, encode_1.encode)(u8, absolutePath, 1, utf8Length);
return u8;
};
exports.encodePathFh = encodePathFh;
const decodePathFh = (fh) => {
const length = fh.length;
if (length < 2)
return undefined;
if (fh[0] !== 1)
return undefined;
return (0, decodeUtf8_1.decodeUtf8)(fh, 1, length - 1);
};
exports.decodePathFh = decodePathFh;
class FileHandleMapper {
constructor(stamp, dir) {
this.dir = dir;
this.idToPath = new Map();
this.pathToId = new Map();
this.maxFhTableSize = 100000;
this.stamp = stamp & 0xffff;
}
decode(fh) {
const length = fh.length;
if (fh.length === 0)
return this.dir;
const type = fh[0];
if (type === 0)
return this.dir;
if (type === 1) {
try {
const path = (0, exports.decodePathFh)(fh);
if (!path)
throw 10001;
return path;
}
catch {
throw 10001;
}
}
if (type === 2) {
if (length !== 8)
throw 10001;
const stamp = (fh[1] << 8) | fh[2];
if (stamp !== this.stamp)
throw 10014;
const id = fh[3] * 0x100000000 + fh[4] * 0x1000000 + (fh[5] << 16) + (fh[6] << 8) + fh[7];
const path = this.idToPath.get(id);
if (!path)
throw 10014;
return path;
}
throw 10001;
}
encode(path) {
if (path === this.dir)
return exports.ROOT_FH;
let fh = this.pathToId.get(path);
if (fh)
return fh;
fh = (0, node_crypto_1.randomBytes)(8);
fh[0] = 2;
fh[1] = (this.stamp >> 8) & 0xff;
fh[2] = this.stamp & 0xff;
const id = fh[3] * 0x100000000 + fh[4] * 0x1000000 + (fh[5] << 16) + (fh[6] << 8) + fh[7];
const { idToPath, pathToId, maxFhTableSize } = this;
ENFORCE_FH_TABLE_SIZE_LIMIT: {
if (idToPath.size <= maxFhTableSize)
break ENFORCE_FH_TABLE_SIZE_LIMIT;
const entry = idToPath.entries().next().value;
if (entry) {
const [id, path] = entry;
idToPath.delete(id);
pathToId.delete(path);
}
}
idToPath.set(id, path);
pathToId.set(path, fh);
return fh;
}
validate(fh) {
if (fh.length === 0)
return true;
const type = fh[0];
if (type === 0)
return true;
if (type === 1)
return true;
if (type === 2)
return true;
return false;
}
currentPath(ctx) {
const cfh = ctx.cfh;
if (!cfh)
throw 10020;
return this.decode(cfh);
}
savedPath(ctx) {
const sfh = ctx.sfh;
if (!sfh)
throw 10020;
return this.decode(sfh);
}
setCfh(ctx, path) {
const newFh = this.encode(path);
ctx.cfh = newFh;
}
remove(path) {
const fh = this.pathToId.get(path);
if (!fh)
return;
const type = fh[0];
if (type !== 2)
return;
const id = fh[3] * 0x100000000 + fh[4] * 0x1000000 + (fh[5] << 16) + (fh[6] << 8) + fh[7];
this.pathToId.delete(path);
this.idToPath.delete(id);
}
rename(oldPath, newPath) {
this.remove(newPath);
const fh = this.pathToId.get(oldPath);
if (!fh)
return;
const type = fh[0];
if (type !== 2)
return;
const id = fh[3] * 0x100000000 + fh[4] * 0x1000000 + (fh[5] << 16) + (fh[6] << 8) + fh[7];
this.pathToId.delete(oldPath);
this.pathToId.set(newPath, fh);
this.idToPath.set(id, newPath);
}
}
exports.FileHandleMapper = FileHandleMapper;
//# sourceMappingURL=fh.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,4 @@
import { Nfsv4Stat } from '../../..';
import type { Logger } from '../../types';
export declare const isErrCode: (code: unknown, error: unknown) => boolean;
export declare const normalizeNodeFsError: (err: unknown, logger: Logger) => Nfsv4Stat;
@@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.normalizeNodeFsError = exports.isErrCode = void 0;
const isErrCode = (code, error) => !!error && typeof error === 'object' && error.code === code;
exports.isErrCode = isErrCode;
const normalizeNodeFsError = (err, logger) => {
if ((0, exports.isErrCode)('ENOENT', err))
return 2;
if ((0, exports.isErrCode)('EACCES', err))
return 13;
if ((0, exports.isErrCode)('EEXIST', err))
return 17;
logger.error('UNEXPECTED_FS_ERROR', err);
return 5;
};
exports.normalizeNodeFsError = normalizeNodeFsError;
//# sourceMappingURL=util.js.map
@@ -0,0 +1 @@
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../../../../../src/nfs/v4/server/operations/node/util.ts"],"names":[],"mappings":";;;AAGO,MAAM,SAAS,GAAG,CAAC,IAAa,EAAE,KAAc,EAAW,EAAE,CAClE,CAAC,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAK,KAAa,CAAC,IAAI,KAAK,IAAI,CAAC;AAD1D,QAAA,SAAS,aACiD;AAEhE,MAAM,oBAAoB,GAAG,CAAC,GAAY,EAAE,MAAc,EAAa,EAAE;IAC9E,IAAI,IAAA,iBAAS,EAAC,QAAQ,EAAE,GAAG,CAAC;QAAE,SAA+B;IAC7D,IAAI,IAAA,iBAAS,EAAC,QAAQ,EAAE,GAAG,CAAC;QAAE,UAAgC;IAC9D,IAAI,IAAA,iBAAS,EAAC,QAAQ,EAAE,GAAG,CAAC;QAAE,UAA+B;IAC7D,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,GAAG,CAAC,CAAC;IACzC,SAA4B;AAC9B,CAAC,CAAC;AANW,QAAA,oBAAoB,wBAM/B"}
+4
View File
@@ -0,0 +1,4 @@
export interface Logger {
log(...args: unknown[]): void;
error(...args: unknown[]): void;
}

Some files were not shown because too many files have changed in this diff Show More