| // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| part of file.src.backends.chroot; |
| |
| class _ChrootDirectory extends _ChrootFileSystemEntity<Directory, io.Directory> |
| with ForwardingDirectory, common.DirectoryAddOnsMixin { |
| _ChrootDirectory(ChrootFileSystem fs, String path) : super(fs, path); |
| |
| factory _ChrootDirectory.wrapped( |
| ChrootFileSystem fs, |
| Directory delegate, { |
| bool relative: false, |
| }) { |
| String localPath = fs._local(delegate.path, relative: relative); |
| return new _ChrootDirectory(fs, localPath); |
| } |
| |
| @override |
| FileSystemEntityType get expectedType => FileSystemEntityType.DIRECTORY; |
| |
| @override |
| io.Directory _rawDelegate(String path) => fileSystem.delegate.directory(path); |
| |
| @override |
| Uri get uri => new Uri.directory(path); |
| |
| @override |
| Future<Directory> rename(String newPath) async { |
| if (_isLink) { |
| if (await fileSystem.type(path) != expectedType) { |
| throw common.notADirectory(path); |
| } |
| FileSystemEntityType type = await fileSystem.type(newPath); |
| if (type != FileSystemEntityType.NOT_FOUND) { |
| if (type != expectedType) { |
| throw common.notADirectory(newPath); |
| } |
| if (!(await fileSystem |
| .directory(newPath) |
| .list(followLinks: false) |
| .isEmpty)) { |
| throw common.directoryNotEmpty(newPath); |
| } |
| } |
| String target = await fileSystem.link(path).target(); |
| await fileSystem.link(path).delete(); |
| await fileSystem.link(newPath).create(target); |
| return fileSystem.directory(newPath); |
| } else { |
| return wrap(await getDelegate(followLinks: true) |
| .rename(fileSystem._real(newPath))); |
| } |
| } |
| |
| @override |
| Directory renameSync(String newPath) { |
| if (_isLink) { |
| if (fileSystem.typeSync(path) != expectedType) { |
| throw common.notADirectory(path); |
| } |
| FileSystemEntityType type = fileSystem.typeSync(newPath); |
| if (type != FileSystemEntityType.NOT_FOUND) { |
| if (type != expectedType) { |
| throw common.notADirectory(newPath); |
| } |
| if (fileSystem |
| .directory(newPath) |
| .listSync(followLinks: false) |
| .isNotEmpty) { |
| throw common.directoryNotEmpty(newPath); |
| } |
| } |
| String target = fileSystem.link(path).targetSync(); |
| fileSystem.link(path).deleteSync(); |
| fileSystem.link(newPath).createSync(target); |
| return fileSystem.directory(newPath); |
| } else { |
| return wrap( |
| getDelegate(followLinks: true).renameSync(fileSystem._real(newPath))); |
| } |
| } |
| |
| @override |
| Directory get absolute => new _ChrootDirectory(fileSystem, _absolutePath); |
| |
| @override |
| Directory get parent { |
| try { |
| return wrapDirectory(delegate.parent); |
| } on _ChrootJailException { |
| return this; |
| } |
| } |
| |
| @override |
| Future<Directory> create({bool recursive: false}) async { |
| if (_isLink) { |
| switch (await fileSystem.type(path)) { |
| case FileSystemEntityType.NOT_FOUND: |
| throw common.noSuchFileOrDirectory(path); |
| case FileSystemEntityType.FILE: |
| throw common.fileExists(path); |
| case FileSystemEntityType.DIRECTORY: |
| // Nothing to do. |
| return this; |
| default: |
| throw new AssertionError(); |
| } |
| } else { |
| return wrap(await delegate.create(recursive: recursive)); |
| } |
| } |
| |
| @override |
| void createSync({bool recursive: false}) { |
| if (_isLink) { |
| switch (fileSystem.typeSync(path)) { |
| case FileSystemEntityType.NOT_FOUND: |
| throw common.noSuchFileOrDirectory(path); |
| case FileSystemEntityType.FILE: |
| throw common.fileExists(path); |
| case FileSystemEntityType.DIRECTORY: |
| // Nothing to do. |
| return; |
| default: |
| throw new AssertionError(); |
| } |
| } else { |
| delegate.createSync(recursive: recursive); |
| } |
| } |
| |
| @override |
| Stream<FileSystemEntity> list({ |
| bool recursive: false, |
| bool followLinks: true, |
| }) { |
| Directory delegate = this.delegate; |
| String dirname = delegate.path; |
| return delegate |
| .list(recursive: recursive, followLinks: followLinks) |
| .map((io.FileSystemEntity entity) => _denormalize(entity, dirname)); |
| } |
| |
| @override |
| List<FileSystemEntity> listSync({ |
| bool recursive: false, |
| bool followLinks: true, |
| }) { |
| Directory delegate = this.delegate; |
| String dirname = delegate.path; |
| return delegate |
| .listSync(recursive: recursive, followLinks: followLinks) |
| .map((io.FileSystemEntity entity) => _denormalize(entity, dirname)) |
| .toList(); |
| } |
| |
| FileSystemEntity _denormalize(io.FileSystemEntity entity, String dirname) { |
| p.Context ctx = fileSystem.path; |
| String relativePart = ctx.relative(entity.path, from: dirname); |
| String entityPath = ctx.join(path, relativePart); |
| if (entity is io.File) { |
| return new _ChrootFile(fileSystem, entityPath); |
| } else if (entity is io.Directory) { |
| return new _ChrootDirectory(fileSystem, entityPath); |
| } else if (entity is io.Link) { |
| return new _ChrootLink(fileSystem, entityPath); |
| } |
| throw new FileSystemException('Unsupported type: $entity', entity.path); |
| } |
| } |