mirror of
https://github.com/hierynomus/sshj.git
synced 2025-12-06 23:30:55 +03:00
Lighter, more coherent interfaces by refactoring LocalFile into LocalSourceFile & LocalDestFile
This commit is contained in:
@@ -16,7 +16,8 @@
|
|||||||
package net.schmizz.sshj.sftp;
|
package net.schmizz.sshj.sftp;
|
||||||
|
|
||||||
import net.schmizz.sshj.xfer.FilePermission;
|
import net.schmizz.sshj.xfer.FilePermission;
|
||||||
import net.schmizz.sshj.xfer.LocalFile;
|
import net.schmizz.sshj.xfer.LocalDestFile;
|
||||||
|
import net.schmizz.sshj.xfer.LocalSourceFile;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -239,12 +240,12 @@ public class SFTPClient
|
|||||||
xfer.upload(source, dest);
|
xfer.upload(source, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void get(String source, LocalFile dest)
|
public void get(String source, LocalDestFile dest)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
xfer.download(source, dest);
|
xfer.download(source, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void put(LocalFile source, String dest)
|
public void put(LocalSourceFile source, String dest)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
xfer.upload(source, dest);
|
xfer.upload(source, dest);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,8 +20,9 @@ import net.schmizz.sshj.sftp.Response.StatusCode;
|
|||||||
import net.schmizz.sshj.xfer.AbstractFileTransfer;
|
import net.schmizz.sshj.xfer.AbstractFileTransfer;
|
||||||
import net.schmizz.sshj.xfer.FileSystemFile;
|
import net.schmizz.sshj.xfer.FileSystemFile;
|
||||||
import net.schmizz.sshj.xfer.FileTransfer;
|
import net.schmizz.sshj.xfer.FileTransfer;
|
||||||
import net.schmizz.sshj.xfer.LocalFile;
|
import net.schmizz.sshj.xfer.LocalDestFile;
|
||||||
import net.schmizz.sshj.xfer.LocalFileFilter;
|
import net.schmizz.sshj.xfer.LocalFileFilter;
|
||||||
|
import net.schmizz.sshj.xfer.LocalSourceFile;
|
||||||
import net.schmizz.sshj.xfer.TransferListener;
|
import net.schmizz.sshj.xfer.TransferListener;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -57,13 +58,13 @@ public class SFTPFileTransfer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void upload(LocalFile localFile, String remotePath)
|
public void upload(LocalSourceFile localFile, String remotePath)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
new Uploader().upload(localFile, remotePath);
|
new Uploader().upload(localFile, remotePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void download(String source, LocalFile dest)
|
public void download(String source, LocalDestFile dest)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
final PathComponents pathComponents = pathHelper.getComponents(source);
|
final PathComponents pathComponents = pathHelper.getComponents(source);
|
||||||
final FileAttributes attributes = engine.stat(source);
|
final FileAttributes attributes = engine.stat(source);
|
||||||
@@ -90,9 +91,9 @@ public class SFTPFileTransfer
|
|||||||
|
|
||||||
private final TransferListener listener = getTransferListener();
|
private final TransferListener listener = getTransferListener();
|
||||||
|
|
||||||
private void download(final RemoteResourceInfo remote, final LocalFile local)
|
private void download(final RemoteResourceInfo remote, final LocalDestFile local)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
final LocalFile adjustedFile;
|
final LocalDestFile adjustedFile;
|
||||||
switch (remote.getAttributes().getType()) {
|
switch (remote.getAttributes().getType()) {
|
||||||
case DIRECTORY:
|
case DIRECTORY:
|
||||||
listener.startedDir(remote.getName());
|
listener.startedDir(remote.getName());
|
||||||
@@ -114,9 +115,9 @@ public class SFTPFileTransfer
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private LocalFile downloadDir(final RemoteResourceInfo remote, final LocalFile local)
|
private LocalDestFile downloadDir(final RemoteResourceInfo remote, final LocalDestFile local)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
final LocalFile adjusted = local.getTargetDirectory(remote.getName());
|
final LocalDestFile adjusted = local.getTargetDirectory(remote.getName());
|
||||||
final RemoteDirectory rd = engine.openDir(remote.getPath());
|
final RemoteDirectory rd = engine.openDir(remote.getPath());
|
||||||
try {
|
try {
|
||||||
for (RemoteResourceInfo rri : rd.scan(getDownloadFilter()))
|
for (RemoteResourceInfo rri : rd.scan(getDownloadFilter()))
|
||||||
@@ -127,9 +128,9 @@ public class SFTPFileTransfer
|
|||||||
return adjusted;
|
return adjusted;
|
||||||
}
|
}
|
||||||
|
|
||||||
private LocalFile downloadFile(final RemoteResourceInfo remote, final LocalFile local)
|
private LocalDestFile downloadFile(final RemoteResourceInfo remote, final LocalDestFile local)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
final LocalFile adjusted = local.getTargetFile(remote.getName());
|
final LocalDestFile adjusted = local.getTargetFile(remote.getName());
|
||||||
final RemoteFile rf = engine.open(remote.getPath());
|
final RemoteFile rf = engine.open(remote.getPath());
|
||||||
try {
|
try {
|
||||||
final OutputStream os = adjusted.getOutputStream();
|
final OutputStream os = adjusted.getOutputStream();
|
||||||
@@ -145,11 +146,11 @@ public class SFTPFileTransfer
|
|||||||
return adjusted;
|
return adjusted;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void copyAttributes(final RemoteResourceInfo remote, final LocalFile local)
|
private void copyAttributes(final RemoteResourceInfo remote, final LocalDestFile local)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
final FileAttributes attrs = remote.getAttributes();
|
final FileAttributes attrs = remote.getAttributes();
|
||||||
local.setPermissions(attrs.getMode().getPermissionsMask());
|
local.setPermissions(attrs.getMode().getPermissionsMask());
|
||||||
if (local.preservesTimes() && attrs.has(FileAttributes.Flag.ACMODTIME)) {
|
if (attrs.has(FileAttributes.Flag.ACMODTIME)) {
|
||||||
local.setLastAccessedTime(attrs.getAtime());
|
local.setLastAccessedTime(attrs.getAtime());
|
||||||
local.setLastModifiedTime(attrs.getMtime());
|
local.setLastModifiedTime(attrs.getMtime());
|
||||||
}
|
}
|
||||||
@@ -161,7 +162,7 @@ public class SFTPFileTransfer
|
|||||||
|
|
||||||
private final TransferListener listener = getTransferListener();
|
private final TransferListener listener = getTransferListener();
|
||||||
|
|
||||||
private void upload(LocalFile local, String remote)
|
private void upload(LocalSourceFile local, String remote)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
final String adjustedPath;
|
final String adjustedPath;
|
||||||
if (local.isDirectory()) {
|
if (local.isDirectory()) {
|
||||||
@@ -169,7 +170,7 @@ public class SFTPFileTransfer
|
|||||||
adjustedPath = uploadDir(local, remote);
|
adjustedPath = uploadDir(local, remote);
|
||||||
listener.finishedDir();
|
listener.finishedDir();
|
||||||
} else if (local.isFile()) {
|
} else if (local.isFile()) {
|
||||||
listener.startedFile(local.getName(), local.length());
|
listener.startedFile(local.getName(), local.getLength());
|
||||||
adjustedPath = uploadFile(local, remote);
|
adjustedPath = uploadFile(local, remote);
|
||||||
listener.finishedFile();
|
listener.finishedFile();
|
||||||
} else
|
} else
|
||||||
@@ -177,15 +178,15 @@ public class SFTPFileTransfer
|
|||||||
engine.setAttributes(adjustedPath, getAttributes(local));
|
engine.setAttributes(adjustedPath, getAttributes(local));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String uploadDir(LocalFile local, String remote)
|
private String uploadDir(LocalSourceFile local, String remote)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
final String adjusted = prepareDir(local, remote);
|
final String adjusted = prepareDir(local, remote);
|
||||||
for (LocalFile f : local.getChildren(getUploadFilter()))
|
for (LocalSourceFile f : local.getChildren(getUploadFilter()))
|
||||||
upload(f, adjusted);
|
upload(f, adjusted);
|
||||||
return adjusted;
|
return adjusted;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String uploadFile(LocalFile local, String remote)
|
private String uploadFile(LocalSourceFile local, String remote)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
final String adjusted = prepareFile(local, remote);
|
final String adjusted = prepareFile(local, remote);
|
||||||
final RemoteFile rf = engine.open(adjusted, EnumSet.of(OpenMode.WRITE,
|
final RemoteFile rf = engine.open(adjusted, EnumSet.of(OpenMode.WRITE,
|
||||||
@@ -205,7 +206,7 @@ public class SFTPFileTransfer
|
|||||||
return adjusted;
|
return adjusted;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String prepareDir(LocalFile local, String remote)
|
private String prepareDir(LocalSourceFile local, String remote)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
final FileAttributes attrs;
|
final FileAttributes attrs;
|
||||||
try {
|
try {
|
||||||
@@ -231,7 +232,7 @@ public class SFTPFileTransfer
|
|||||||
throw new IOException(attrs.getMode().getType() + " file already exists at " + remote);
|
throw new IOException(attrs.getMode().getType() + " file already exists at " + remote);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String prepareFile(LocalFile local, String remote)
|
private String prepareFile(LocalSourceFile local, String remote)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
final FileAttributes attrs;
|
final FileAttributes attrs;
|
||||||
try {
|
try {
|
||||||
@@ -253,10 +254,10 @@ public class SFTPFileTransfer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private FileAttributes getAttributes(LocalFile local)
|
private FileAttributes getAttributes(LocalSourceFile local)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
final FileAttributes.Builder builder = new FileAttributes.Builder().withPermissions(local.getPermissions());
|
final FileAttributes.Builder builder = new FileAttributes.Builder().withPermissions(local.getPermissions());
|
||||||
if (local.preservesTimes())
|
if (local.providesAtimeMtime())
|
||||||
builder.withAtimeMtime(local.getLastAccessTime(), local.getLastModifiedTime());
|
builder.withAtimeMtime(local.getLastAccessTime(), local.getLastModifiedTime());
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class FileSystemFile
|
public class FileSystemFile
|
||||||
implements LocalFile {
|
implements LocalSourceFile, LocalDestFile {
|
||||||
|
|
||||||
protected final Logger log = LoggerFactory.getLogger(getClass());
|
protected final Logger log = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ public class FileSystemFile
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long length() {
|
public long getLength() {
|
||||||
return file.length();
|
return file.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,12 +81,6 @@ public class FileSystemFile
|
|||||||
return new FileOutputStream(file);
|
return new FileOutputStream(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterable<FileSystemFile> getChildren()
|
|
||||||
throws IOException {
|
|
||||||
return getChildren(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<FileSystemFile> getChildren(final LocalFileFilter filter)
|
public Iterable<FileSystemFile> getChildren(final LocalFileFilter filter)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
@@ -111,6 +105,11 @@ public class FileSystemFile
|
|||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean providesAtimeMtime() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getLastAccessTime()
|
public long getLastAccessTime()
|
||||||
throws IOException {
|
throws IOException {
|
||||||
@@ -160,11 +159,6 @@ public class FileSystemFile
|
|||||||
log.warn("Could not set permissions for {} to {}", file, Integer.toString(perms, 16));
|
log.warn("Could not set permissions for {} to {}", file, Integer.toString(perms, 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean preservesTimes() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FileSystemFile getChild(String name) {
|
public FileSystemFile getChild(String name) {
|
||||||
return new FileSystemFile(new File(file, name));
|
return new FileSystemFile(new File(file, name));
|
||||||
|
|||||||
@@ -25,10 +25,10 @@ public interface FileTransfer {
|
|||||||
void download(String remotePath, String localPath)
|
void download(String remotePath, String localPath)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
|
|
||||||
void upload(LocalFile localFile, String remotePath)
|
void upload(LocalSourceFile localFile, String remotePath)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
|
|
||||||
void download(String remotePath, LocalFile localFile)
|
void download(String remotePath, LocalDestFile localFile)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
|
|
||||||
TransferListener getTransferListener();
|
TransferListener getTransferListener();
|
||||||
|
|||||||
@@ -19,123 +19,45 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
public class InMemoryDestFile
|
public abstract class InMemoryDestFile
|
||||||
implements LocalFile {
|
implements LocalDestFile {
|
||||||
|
|
||||||
protected final Logger log = LoggerFactory.getLogger(getClass());
|
protected final Logger log = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
protected final String filename;
|
|
||||||
protected final OutputStream outStream;
|
|
||||||
|
|
||||||
public InMemoryDestFile(String filename, OutputStream outStream) {
|
|
||||||
this.filename = filename;
|
|
||||||
this.outStream = outStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public InMemoryDestFile getTargetFile(String filename)
|
||||||
return filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LocalFile getTargetFile(String filename)
|
|
||||||
throws IOException {
|
throws IOException {
|
||||||
if (filename.equals(this.filename))
|
|
||||||
return this;
|
return this;
|
||||||
else
|
|
||||||
throw new IOException("Filename mismatch");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFile() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDirectory() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public OutputStream getOutputStream()
|
|
||||||
throws IOException {
|
|
||||||
return outStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Everything else is unimplemented
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long length() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InputStream getInputStream()
|
|
||||||
throws IOException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterable<LocalFile> getChildren()
|
|
||||||
throws IOException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterable<LocalFile> getChildren(LocalFileFilter filter)
|
|
||||||
throws IOException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getLastAccessTime()
|
|
||||||
throws IOException {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getLastModifiedTime()
|
|
||||||
throws IOException {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPermissions()
|
|
||||||
throws IOException {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setLastAccessedTime(long t)
|
public void setLastAccessedTime(long t)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
log.info("atime = {}", t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setLastModifiedTime(long t)
|
public void setLastModifiedTime(long t)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
log.info("mtime = {}", t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setPermissions(int perms)
|
public void setPermissions(int perms)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
log.info("permissions = {}", Integer.toOctalString(perms));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean preservesTimes() {
|
public LocalDestFile getTargetDirectory(String dirname)
|
||||||
return false;
|
throws IOException {
|
||||||
|
throw new AssertionError("Unimplemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LocalFile getChild(String name) {
|
public LocalDestFile getChild(String name) {
|
||||||
return null;
|
throw new AssertionError("Unimplemented");
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LocalFile getTargetDirectory(String dirname) {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,38 +19,12 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
public class InMemorySourceFile
|
public abstract class InMemorySourceFile
|
||||||
implements LocalFile {
|
implements LocalSourceFile {
|
||||||
|
|
||||||
protected final Logger log = LoggerFactory.getLogger(getClass());
|
protected final Logger log = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
protected final String filename;
|
|
||||||
protected final long length;
|
|
||||||
protected final InputStream inStream;
|
|
||||||
|
|
||||||
public InMemorySourceFile(String filename, long length, InputStream inStream) {
|
|
||||||
this.filename = filename;
|
|
||||||
this.length = length;
|
|
||||||
this.inStream = inStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LocalFile getTargetFile(String filename)
|
|
||||||
throws IOException {
|
|
||||||
if (filename.equals(this.filename))
|
|
||||||
return this;
|
|
||||||
else
|
|
||||||
throw new IOException("Filename mismatch");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFile() {
|
public boolean isFile() {
|
||||||
return true;
|
return true;
|
||||||
@@ -61,83 +35,33 @@ public class InMemorySourceFile
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public long length() {
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InputStream getInputStream()
|
|
||||||
throws IOException {
|
|
||||||
return inStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getPermissions()
|
public int getPermissions()
|
||||||
throws IOException {
|
throws IOException {
|
||||||
return 0644;
|
return 0644;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Everything else is unimplemented
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OutputStream getOutputStream()
|
public boolean providesAtimeMtime() {
|
||||||
throws IOException {
|
return false;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterable<LocalFile> getChildren()
|
|
||||||
throws IOException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterable<LocalFile> getChildren(LocalFileFilter filter)
|
|
||||||
throws IOException {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getLastAccessTime()
|
public long getLastAccessTime()
|
||||||
throws IOException {
|
throws IOException {
|
||||||
return 0;
|
throw new AssertionError("Unimplemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getLastModifiedTime()
|
public long getLastModifiedTime()
|
||||||
throws IOException {
|
throws IOException {
|
||||||
return 0;
|
throw new AssertionError("Unimplemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setLastAccessedTime(long t)
|
public Iterable<? extends LocalSourceFile> getChildren(LocalFileFilter filter)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
}
|
throw new AssertionError("Unimplemented");
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setLastModifiedTime(long t)
|
|
||||||
throws IOException {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPermissions(int perms)
|
|
||||||
throws IOException {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean preservesTimes() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LocalFile getChild(String name) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LocalFile getTargetDirectory(String dirname) {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,57 +16,41 @@
|
|||||||
package net.schmizz.sshj.xfer;
|
package net.schmizz.sshj.xfer;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
// TODO Document all methods properly
|
public interface LocalDestFile {
|
||||||
|
|
||||||
public interface LocalFile {
|
OutputStream getOutputStream()
|
||||||
|
throws IOException;
|
||||||
|
|
||||||
String getName();
|
/** @return A child file/directory of this directory with given {@code name}. */
|
||||||
|
LocalDestFile getChild(String name);
|
||||||
boolean isFile();
|
|
||||||
|
|
||||||
boolean isDirectory();
|
|
||||||
|
|
||||||
long length();
|
|
||||||
|
|
||||||
InputStream getInputStream() throws IOException;
|
|
||||||
|
|
||||||
OutputStream getOutputStream() throws IOException;
|
|
||||||
|
|
||||||
Iterable<? extends LocalFile> getChildren() throws IOException;
|
|
||||||
|
|
||||||
Iterable<? extends LocalFile> getChildren(LocalFileFilter filter) throws IOException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns last access time for the underlying file.
|
* Allows caller to express intent that caller expects to write to file with {@code filename}. Based on this
|
||||||
*
|
* information, an implementation may return an alternate file to write to, which should be respected by the
|
||||||
* @return time in seconds since Unix epoch
|
* caller.
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
*/
|
||||||
long getLastAccessTime()
|
LocalDestFile getTargetFile(String filename)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns last access time for the underlying file.
|
* Allows caller to express intent that caller expects to write to directory with {@code dirname}. Based on this
|
||||||
*
|
* information, an implementation may return an alternate directory to write to, which should be respected by the
|
||||||
* @return time in seconds since Unix epoch
|
* caller.
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
*/
|
||||||
long getLastModifiedTime()
|
LocalDestFile getTargetDirectory(String dirname)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the permissions for the underlying file
|
* Set the permissions for the underlying file.
|
||||||
*
|
*
|
||||||
* @return permissions in octal format, e.g. 0644
|
* @param f the file
|
||||||
|
* @param perms permissions e.g. 0644
|
||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
int getPermissions()
|
void setPermissions(int perms)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -90,25 +74,4 @@ public interface LocalFile {
|
|||||||
void setLastModifiedTime(long t)
|
void setLastModifiedTime(long t)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the permissions for the underlying file.
|
|
||||||
*
|
|
||||||
* @param f the file
|
|
||||||
* @param perms permissions in octal format, e.g. 0644
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
void setPermissions(int perms)
|
|
||||||
throws IOException;
|
|
||||||
|
|
||||||
/** @return whether this implementation is interested in preserving mtime and atime. */
|
|
||||||
boolean preservesTimes();
|
|
||||||
|
|
||||||
/** @return A child file of this directory having {@code name} as filename */
|
|
||||||
LocalFile getChild(String name);
|
|
||||||
|
|
||||||
LocalFile getTargetFile(String filename) throws IOException;
|
|
||||||
|
|
||||||
LocalFile getTargetDirectory(String dirname) throws IOException;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -17,6 +17,6 @@ package net.schmizz.sshj.xfer;
|
|||||||
|
|
||||||
public interface LocalFileFilter {
|
public interface LocalFileFilter {
|
||||||
|
|
||||||
boolean accept(LocalFile file);
|
boolean accept(LocalSourceFile file);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
68
src/main/java/net/schmizz/sshj/xfer/LocalSourceFile.java
Normal file
68
src/main/java/net/schmizz/sshj/xfer/LocalSourceFile.java
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011 sshj contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package net.schmizz.sshj.xfer;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
public interface LocalSourceFile {
|
||||||
|
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
long getLength();
|
||||||
|
|
||||||
|
InputStream getInputStream()
|
||||||
|
throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the permissions for the underlying file
|
||||||
|
*
|
||||||
|
* @return permissions e.g. 0644
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
int getPermissions() throws IOException;
|
||||||
|
|
||||||
|
boolean isFile();
|
||||||
|
|
||||||
|
boolean isDirectory();
|
||||||
|
|
||||||
|
Iterable<? extends LocalSourceFile> getChildren(LocalFileFilter filter)
|
||||||
|
throws IOException;
|
||||||
|
|
||||||
|
boolean providesAtimeMtime();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns last access time for the underlying file.
|
||||||
|
*
|
||||||
|
* @return time in seconds since Unix epoch
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
long getLastAccessTime()
|
||||||
|
throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns last access time for the underlying file.
|
||||||
|
*
|
||||||
|
* @return time in seconds since Unix epoch
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
long getLastModifiedTime()
|
||||||
|
throws IOException;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -21,7 +21,7 @@ import java.util.LinkedList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import net.schmizz.sshj.common.IOUtils;
|
import net.schmizz.sshj.common.IOUtils;
|
||||||
import net.schmizz.sshj.xfer.LocalFile;
|
import net.schmizz.sshj.xfer.LocalDestFile;
|
||||||
import net.schmizz.sshj.xfer.scp.SCPEngine.Arg;
|
import net.schmizz.sshj.xfer.scp.SCPEngine.Arg;
|
||||||
|
|
||||||
/** Support for uploading files over a connected link using SCP. */
|
/** Support for uploading files over a connected link using SCP. */
|
||||||
@@ -36,7 +36,7 @@ public final class SCPDownloadClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Download a file from {@code sourcePath} on the connected host to {@code targetPath} locally. */
|
/** Download a file from {@code sourcePath} on the connected host to {@code targetPath} locally. */
|
||||||
public synchronized int copy(String sourcePath, LocalFile targetFile)
|
public synchronized int copy(String sourcePath, LocalDestFile targetFile)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
engine.cleanSlate();
|
engine.cleanSlate();
|
||||||
try {
|
try {
|
||||||
@@ -55,15 +55,14 @@ public final class SCPDownloadClient {
|
|||||||
this.recursive = recursive;
|
this.recursive = recursive;
|
||||||
}
|
}
|
||||||
|
|
||||||
void startCopy(String sourcePath, LocalFile targetFile)
|
void startCopy(String sourcePath, LocalDestFile targetFile)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
List<Arg> args = new LinkedList<Arg>();
|
List<Arg> args = new LinkedList<Arg>();
|
||||||
args.add(Arg.SOURCE);
|
args.add(Arg.SOURCE);
|
||||||
args.add(Arg.QUIET);
|
args.add(Arg.QUIET);
|
||||||
|
args.add(Arg.PRESERVE_TIMES);
|
||||||
if (recursive)
|
if (recursive)
|
||||||
args.add(Arg.RECURSIVE);
|
args.add(Arg.RECURSIVE);
|
||||||
if (targetFile.preservesTimes())
|
|
||||||
args.add(Arg.PRESERVE_TIMES);
|
|
||||||
engine.execSCPWith(args, sourcePath);
|
engine.execSCPWith(args, sourcePath);
|
||||||
|
|
||||||
engine.signal("Start status OK");
|
engine.signal("Start status OK");
|
||||||
@@ -92,7 +91,7 @@ public final class SCPDownloadClient {
|
|||||||
return Integer.parseInt(cmd.substring(1), 8);
|
return Integer.parseInt(cmd.substring(1), 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean process(String bufferedTMsg, String msg, LocalFile f)
|
private boolean process(String bufferedTMsg, String msg, LocalDestFile f)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
if (msg.length() < 1)
|
if (msg.length() < 1)
|
||||||
throw new SCPException("Could not parse message `" + msg + "`");
|
throw new SCPException("Could not parse message `" + msg + "`");
|
||||||
@@ -128,7 +127,7 @@ public final class SCPDownloadClient {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processDirectory(String dMsg, String tMsg, LocalFile f)
|
private void processDirectory(String dMsg, String tMsg, LocalDestFile f)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
final String[] dMsgParts = tokenize(dMsg, 3); // D<perms> 0 <dirname>
|
final String[] dMsgParts = tokenize(dMsg, 3); // D<perms> 0 <dirname>
|
||||||
final long length = parseLong(dMsgParts[1], "dir length");
|
final long length = parseLong(dMsgParts[1], "dir length");
|
||||||
@@ -147,20 +146,20 @@ public final class SCPDownloadClient {
|
|||||||
engine.finishedDir();
|
engine.finishedDir();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processFile(String cMsg, String tMsg, LocalFile f)
|
private void processFile(String cMsg, String tMsg, LocalDestFile f)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
final String[] cMsgParts = tokenize(cMsg, 3); // C<perms> <size> <filename>
|
final String[] cMsgParts = tokenize(cMsg, 3); // C<perms> <size> <filename>
|
||||||
final long length = parseLong(cMsgParts[1], "length");
|
final long length = parseLong(cMsgParts[1], "length");
|
||||||
final String filename = cMsgParts[2];
|
final String filename = cMsgParts[2];
|
||||||
engine.startedFile(length, filename);
|
engine.startedFile(filename, length);
|
||||||
{
|
{
|
||||||
f = f.getTargetFile(filename);
|
f = f.getTargetFile(filename);
|
||||||
engine.signal("Remote can start transfer");
|
engine.signal("Remote can start transfer");
|
||||||
final OutputStream os = f.getOutputStream();
|
final OutputStream dest = f.getOutputStream();
|
||||||
try {
|
try {
|
||||||
engine.transferFromRemote(length, os);
|
engine.transferFromRemote(dest, length);
|
||||||
} finally {
|
} finally {
|
||||||
IOUtils.closeQuietly(os);
|
IOUtils.closeQuietly(dest);
|
||||||
}
|
}
|
||||||
engine.check("Remote agrees transfer done");
|
engine.check("Remote agrees transfer done");
|
||||||
setAttributes(f, parsePermissions(cMsgParts[0]), tMsg);
|
setAttributes(f, parsePermissions(cMsgParts[0]), tMsg);
|
||||||
@@ -169,10 +168,10 @@ public final class SCPDownloadClient {
|
|||||||
engine.finishedFile();
|
engine.finishedFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setAttributes(LocalFile f, int perms, String tMsg)
|
private void setAttributes(LocalDestFile f, int perms, String tMsg)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
f.setPermissions(perms);
|
f.setPermissions(perms);
|
||||||
if (tMsg != null && f.preservesTimes()) {
|
if (tMsg != null) {
|
||||||
String[] tMsgParts = tokenize(tMsg, 4); // e.g. T<mtime> 0 <atime> 0
|
String[] tMsgParts = tokenize(tMsg, 4); // e.g. T<mtime> 0 <atime> 0
|
||||||
f.setLastModifiedTime(parseLong(tMsgParts[0].substring(1), "last modified time"));
|
f.setLastModifiedTime(parseLong(tMsgParts[0].substring(1), "last modified time"));
|
||||||
f.setLastAccessedTime(parseLong(tMsgParts[2], "last access time"));
|
f.setLastAccessedTime(parseLong(tMsgParts[2], "last access time"));
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import net.schmizz.sshj.common.IOUtils;
|
|||||||
import net.schmizz.sshj.common.SSHException;
|
import net.schmizz.sshj.common.SSHException;
|
||||||
import net.schmizz.sshj.connection.channel.direct.Session.Command;
|
import net.schmizz.sshj.connection.channel.direct.Session.Command;
|
||||||
import net.schmizz.sshj.connection.channel.direct.SessionFactory;
|
import net.schmizz.sshj.connection.channel.direct.SessionFactory;
|
||||||
import net.schmizz.sshj.xfer.LocalFile;
|
|
||||||
import net.schmizz.sshj.xfer.TransferListener;
|
import net.schmizz.sshj.xfer.TransferListener;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -161,14 +160,14 @@ class SCPEngine {
|
|||||||
scp.getOutputStream().flush();
|
scp.getOutputStream().flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void transferToRemote(LocalFile f, final InputStream src)
|
void transferToRemote(final InputStream src, final long length)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
transfer(src, scp.getOutputStream(), scp.getRemoteMaxPacketSize(), f.length());
|
transfer(src, scp.getOutputStream(), scp.getRemoteMaxPacketSize(), length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void transferFromRemote(final long length, final OutputStream os)
|
void transferFromRemote(final OutputStream dest, final long length)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
transfer(scp.getInputStream(), os, scp.getLocalMaxPacketSize(), length);
|
transfer(scp.getInputStream(), dest, scp.getLocalMaxPacketSize(), length);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void transfer(InputStream in, OutputStream out, int bufSize, long len)
|
private void transfer(InputStream in, OutputStream out, int bufSize, long len)
|
||||||
@@ -198,22 +197,14 @@ class SCPEngine {
|
|||||||
listener.startedDir(dirname);
|
listener.startedDir(dirname);
|
||||||
}
|
}
|
||||||
|
|
||||||
void startedDir(LocalFile f) {
|
|
||||||
listener.startedDir(f.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
void finishedDir() {
|
void finishedDir() {
|
||||||
listener.finishedDir();
|
listener.finishedDir();
|
||||||
}
|
}
|
||||||
|
|
||||||
void startedFile(final long length, final String filename) {
|
void startedFile(final String filename, final long length) {
|
||||||
listener.startedFile(filename, length);
|
listener.startedFile(filename, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void startedFile(LocalFile f) {
|
|
||||||
listener.startedFile(f.getName(), f.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
void finishedFile() {
|
void finishedFile() {
|
||||||
listener.finishedFile();
|
listener.finishedFile();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ import net.schmizz.sshj.connection.channel.direct.SessionFactory;
|
|||||||
import net.schmizz.sshj.xfer.AbstractFileTransfer;
|
import net.schmizz.sshj.xfer.AbstractFileTransfer;
|
||||||
import net.schmizz.sshj.xfer.FileSystemFile;
|
import net.schmizz.sshj.xfer.FileSystemFile;
|
||||||
import net.schmizz.sshj.xfer.FileTransfer;
|
import net.schmizz.sshj.xfer.FileTransfer;
|
||||||
import net.schmizz.sshj.xfer.LocalFile;
|
import net.schmizz.sshj.xfer.LocalDestFile;
|
||||||
|
import net.schmizz.sshj.xfer.LocalSourceFile;
|
||||||
|
|
||||||
public class SCPFileTransfer
|
public class SCPFileTransfer
|
||||||
extends AbstractFileTransfer
|
extends AbstractFileTransfer
|
||||||
@@ -58,13 +59,13 @@ public class SCPFileTransfer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void download(String remotePath, LocalFile localFile)
|
public void download(String remotePath, LocalDestFile localFile)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
newSCPDownloadClient().copy(remotePath, localFile);
|
newSCPDownloadClient().copy(remotePath, localFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void upload(LocalFile localFile, String remotePath)
|
public void upload(LocalSourceFile localFile, String remotePath)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
newSCPUploadClient().copy(localFile, remotePath);
|
newSCPUploadClient().copy(localFile, remotePath);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
package net.schmizz.sshj.xfer.scp;
|
package net.schmizz.sshj.xfer.scp;
|
||||||
|
|
||||||
import net.schmizz.sshj.common.IOUtils;
|
import net.schmizz.sshj.common.IOUtils;
|
||||||
import net.schmizz.sshj.xfer.LocalFile;
|
import net.schmizz.sshj.xfer.LocalSourceFile;
|
||||||
import net.schmizz.sshj.xfer.scp.SCPEngine.Arg;
|
import net.schmizz.sshj.xfer.scp.SCPEngine.Arg;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -34,7 +34,7 @@ public final class SCPUploadClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Upload a local file from {@code localFile} to {@code targetPath} on the remote host. */
|
/** Upload a local file from {@code localFile} to {@code targetPath} on the remote host. */
|
||||||
public synchronized int copy(LocalFile sourceFile, String remotePath)
|
public synchronized int copy(LocalSourceFile sourceFile, String remotePath)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
engine.cleanSlate();
|
engine.cleanSlate();
|
||||||
try {
|
try {
|
||||||
@@ -45,48 +45,48 @@ public final class SCPUploadClient {
|
|||||||
return engine.getExitStatus();
|
return engine.getExitStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void startCopy(LocalFile sourceFile, String targetPath)
|
private synchronized void startCopy(LocalSourceFile sourceFile, String targetPath)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
List<Arg> args = new LinkedList<Arg>();
|
List<Arg> args = new LinkedList<Arg>();
|
||||||
args.add(Arg.SINK);
|
args.add(Arg.SINK);
|
||||||
args.add(Arg.RECURSIVE);
|
args.add(Arg.RECURSIVE);
|
||||||
if (sourceFile.preservesTimes())
|
if (sourceFile.providesAtimeMtime())
|
||||||
args.add(Arg.PRESERVE_TIMES);
|
args.add(Arg.PRESERVE_TIMES);
|
||||||
engine.execSCPWith(args, targetPath);
|
engine.execSCPWith(args, targetPath);
|
||||||
engine.check("Start status OK");
|
engine.check("Start status OK");
|
||||||
process(sourceFile);
|
process(sourceFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void process(LocalFile f)
|
private void process(LocalSourceFile f)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
if (f.isDirectory()) {
|
if (f.isDirectory()) {
|
||||||
engine.startedDir(f);
|
engine.startedDir(f.getName());
|
||||||
sendDirectory(f);
|
sendDirectory(f);
|
||||||
engine.finishedDir();
|
engine.finishedDir();
|
||||||
} else if (f.isFile()) {
|
} else if (f.isFile()) {
|
||||||
engine.startedFile(f);
|
engine.startedFile(f.getName(), f.getLength());
|
||||||
sendFile(f);
|
sendFile(f);
|
||||||
engine.finishedFile();
|
engine.finishedFile();
|
||||||
} else
|
} else
|
||||||
throw new IOException(f + " is not a regular file or directory");
|
throw new IOException(f + " is not a regular file or directory");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendDirectory(LocalFile f)
|
private void sendDirectory(LocalSourceFile f)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
preserveTimeIfPossible(f);
|
preserveTimeIfPossible(f);
|
||||||
engine.sendMessage("D0" + getPermString(f) + " 0 " + f.getName());
|
engine.sendMessage("D0" + getPermString(f) + " 0 " + f.getName());
|
||||||
for (LocalFile child : f.getChildren())
|
for (LocalSourceFile child : f.getChildren(null))
|
||||||
process(child);
|
process(child);
|
||||||
engine.sendMessage("E");
|
engine.sendMessage("E");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendFile(LocalFile f)
|
private void sendFile(LocalSourceFile f)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
preserveTimeIfPossible(f);
|
preserveTimeIfPossible(f);
|
||||||
final InputStream src = f.getInputStream();
|
final InputStream src = f.getInputStream();
|
||||||
try {
|
try {
|
||||||
engine.sendMessage("C0" + getPermString(f) + " " + f.length() + " " + f.getName());
|
engine.sendMessage("C0" + getPermString(f) + " " + f.getLength() + " " + f.getName());
|
||||||
engine.transferToRemote(f, src);
|
engine.transferToRemote(src, f.getLength());
|
||||||
engine.signal("Transfer done");
|
engine.signal("Transfer done");
|
||||||
engine.check("Remote agrees transfer done");
|
engine.check("Remote agrees transfer done");
|
||||||
} finally {
|
} finally {
|
||||||
@@ -94,13 +94,13 @@ public final class SCPUploadClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void preserveTimeIfPossible(LocalFile f)
|
private void preserveTimeIfPossible(LocalSourceFile f)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
if (f.preservesTimes())
|
if (f.providesAtimeMtime())
|
||||||
engine.sendMessage("T" + f.getLastModifiedTime() + " 0 " + f.getLastAccessTime() + " 0");
|
engine.sendMessage("T" + f.getLastModifiedTime() + " 0 " + f.getLastAccessTime() + " 0");
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getPermString(LocalFile f)
|
private String getPermString(LocalSourceFile f)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
return Integer.toOctalString(f.getPermissions() & 07777);
|
return Integer.toOctalString(f.getPermissions() & 07777);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user