|
1 | 1 | import type {Stats} from 'node:fs'; |
2 | 2 | import * as NodePath from 'node:path'; |
3 | 3 | import {randomBytes} from 'node:crypto'; |
4 | | -import {Nfsv4Const, Nfsv4Stat} from '../../../constants'; |
| 4 | +import {Nfsv4Access, Nfsv4Const, Nfsv4Stat} from '../../../constants'; |
5 | 5 | import {Nfsv4OperationCtx, Nfsv4Operations} from '../Nfsv4Operations'; |
6 | 6 | import * as msg from '../../../messages'; |
7 | 7 | import * as struct from '../../../structs'; |
@@ -322,14 +322,55 @@ export class Nfsv4OperationsNode implements Nfsv4Operations { |
322 | 322 | return new msg.Nfsv4GetattrResponse(Nfsv4Stat.NFS4_OK, new msg.Nfsv4GetattrResOk(attrs)); |
323 | 323 | } |
324 | 324 |
|
325 | | - // ----------------------------------------------- Stub implementations below |
326 | | - |
327 | 325 | 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); |
331 | 370 | } |
332 | 371 |
|
| 372 | + // ----------------------------------------------- Stub implementations below |
| 373 | + |
333 | 374 | public async CLOSE(request: msg.Nfsv4CloseRequest, ctx: Nfsv4OperationCtx): Promise<msg.Nfsv4CloseResponse> { |
334 | 375 | ctx.connection.logger.log('CLOSE', request); |
335 | 376 | throw new Error('Not implemented'); |
|
0 commit comments