Skip to content

Commit 6ac80a1

Browse files
committed
feat: 🎸 add ACCESS operation implementation
1 parent 5fd580c commit 6ac80a1

File tree

1 file changed

+47
-6
lines changed

1 file changed

+47
-6
lines changed

src/nfs/v4/server/operations/node/Nfsv4OperationsNode.ts

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type {Stats} from 'node:fs';
22
import * as NodePath from 'node:path';
33
import {randomBytes} from 'node:crypto';
4-
import {Nfsv4Const, Nfsv4Stat} from '../../../constants';
4+
import {Nfsv4Access, Nfsv4Const, Nfsv4Stat} from '../../../constants';
55
import {Nfsv4OperationCtx, Nfsv4Operations} from '../Nfsv4Operations';
66
import * as msg from '../../../messages';
77
import * as struct from '../../../structs';
@@ -322,14 +322,55 @@ export class Nfsv4OperationsNode implements Nfsv4Operations {
322322
return new msg.Nfsv4GetattrResponse(Nfsv4Stat.NFS4_OK, new msg.Nfsv4GetattrResOk(attrs));
323323
}
324324

325-
// ----------------------------------------------- Stub implementations below
326-
327325
public async ACCESS(request: msg.Nfsv4AccessRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4AccessResponse> {
328-
ctx.connection.logger.log('ACCESS', request);
329-
throw new Error('Not implemented');
330-
return new msg.Nfsv4AccessResponse(Nfsv4Stat.NFS4ERR_SERVERFAULT);
326+
const path = this.fh.currentPath(ctx);
327+
const absolutePath = this.absolutePath(path);
328+
const promises = this.promises;
329+
let stats: Stats;
330+
try {
331+
stats = await promises.lstat(absolutePath);
332+
} catch (error: unknown) {
333+
throw normalizeNodeFsError(error, ctx.connection.logger);
334+
}
335+
const requestedAccess = request.access;
336+
const isDirectory = stats.isDirectory();
337+
const mode = stats.mode;
338+
let supported = 0;
339+
let access = 0;
340+
if (requestedAccess & Nfsv4Access.ACCESS4_READ) {
341+
supported |= Nfsv4Access.ACCESS4_READ;
342+
if (mode & 0o444) access |= Nfsv4Access.ACCESS4_READ;
343+
}
344+
if (requestedAccess & Nfsv4Access.ACCESS4_LOOKUP) {
345+
supported |= Nfsv4Access.ACCESS4_LOOKUP;
346+
if (isDirectory && (mode & 0o111)) access |= Nfsv4Access.ACCESS4_LOOKUP;
347+
}
348+
if (requestedAccess & Nfsv4Access.ACCESS4_MODIFY) {
349+
supported |= Nfsv4Access.ACCESS4_MODIFY;
350+
if (mode & 0o222) access |= Nfsv4Access.ACCESS4_MODIFY;
351+
}
352+
if (requestedAccess & Nfsv4Access.ACCESS4_EXTEND) {
353+
supported |= Nfsv4Access.ACCESS4_EXTEND;
354+
if (mode & 0o222) access |= Nfsv4Access.ACCESS4_EXTEND;
355+
}
356+
if (requestedAccess & Nfsv4Access.ACCESS4_DELETE) {
357+
if (!isDirectory) {
358+
supported |= 0;
359+
} else {
360+
supported |= Nfsv4Access.ACCESS4_DELETE;
361+
if (mode & 0o222) access |= Nfsv4Access.ACCESS4_DELETE;
362+
}
363+
}
364+
if (requestedAccess & Nfsv4Access.ACCESS4_EXECUTE) {
365+
supported |= Nfsv4Access.ACCESS4_EXECUTE;
366+
if (!isDirectory && (mode & 0o111)) access |= Nfsv4Access.ACCESS4_EXECUTE;
367+
}
368+
const body = new msg.Nfsv4AccessResOk(supported, access);
369+
return new msg.Nfsv4AccessResponse(Nfsv4Stat.NFS4_OK, body);
331370
}
332371

372+
// ----------------------------------------------- Stub implementations below
373+
333374
public async CLOSE(request: msg.Nfsv4CloseRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4CloseResponse> {
334375
ctx.connection.logger.log('CLOSE', request);
335376
throw new Error('Not implemented');

0 commit comments

Comments
 (0)