diff --git a/src/main/java/net/schmizz/sshj/SSHClient.java b/src/main/java/net/schmizz/sshj/SSHClient.java index deef70c41..4c84cdde5 100644 --- a/src/main/java/net/schmizz/sshj/SSHClient.java +++ b/src/main/java/net/schmizz/sshj/SSHClient.java @@ -212,7 +212,7 @@ public void auth(String username, AuthMethod... methods) public void auth(String username, Iterable methods) throws UserAuthException, TransportException { checkConnected(); - final Deque savedEx = new LinkedList<>(); + final Deque savedEx = new LinkedList(); for (AuthMethod method: methods) { method.setLoggerFactory(loggerFactory); try { @@ -334,7 +334,7 @@ public void authPublickey(String username) */ public void authPublickey(String username, Iterable keyProviders) throws UserAuthException, TransportException { - final List am = new LinkedList<>(); + final List am = new LinkedList(); for (KeyProvider kp : keyProviders) am.add(new AuthPublickey(kp)); auth(username, am); @@ -377,7 +377,7 @@ public void authPublickey(String username, KeyProvider... keyProviders) */ public void authPublickey(String username, String... locations) throws UserAuthException, TransportException { - final List keyProviders = new LinkedList<>(); + final List keyProviders = new LinkedList(); for (String loc : locations) { try { log.debug("Attempting to load key from: {}", loc); @@ -407,7 +407,7 @@ public void authPublickey(String username, String... locations) public void authGssApiWithMic(String username, LoginContext context, Oid supportedOid, Oid... supportedOids) throws UserAuthException, TransportException { // insert supportedOid to the front of the list since ordering matters - List oids = new ArrayList<>(Arrays.asList(supportedOids)); + List oids = new ArrayList(Arrays.asList(supportedOids)); oids.add(0, supportedOid); auth(username, new AuthGssApiWithMic(context, oids)); diff --git a/src/main/java/net/schmizz/sshj/connection/channel/AbstractChannel.java b/src/main/java/net/schmizz/sshj/connection/channel/AbstractChannel.java index 215f14bd6..fa89f028e 100644 --- a/src/main/java/net/schmizz/sshj/connection/channel/AbstractChannel.java +++ b/src/main/java/net/schmizz/sshj/connection/channel/AbstractChannel.java @@ -52,6 +52,8 @@ public abstract class AbstractChannel /** Remote recipient ID */ private int recipient; + private boolean eof = false; + private final Queue> chanReqResponseEvents = new LinkedList>(); /* The lock used by to create the open & close events */ @@ -191,9 +193,14 @@ public void handle(Message msg, SSHPacket buf) } } + @Override + public boolean isEOF() { + return eof; + } + @Override public LoggerFactory getLoggerFactory() { - return loggerFactory; + return loggerFactory; } private void gotClose() @@ -394,6 +401,7 @@ private void gotEOF() /** Called when EOF has been received. Subclasses can override but must call super. */ protected void eofInputStreams() { in.eof(); + eof = true; } @Override diff --git a/src/main/java/net/schmizz/sshj/connection/channel/Channel.java b/src/main/java/net/schmizz/sshj/connection/channel/Channel.java index 3d76f9a48..177938222 100644 --- a/src/main/java/net/schmizz/sshj/connection/channel/Channel.java +++ b/src/main/java/net/schmizz/sshj/connection/channel/Channel.java @@ -156,6 +156,11 @@ interface Forwarded extends Channel { void join(long timeout, TimeUnit unit) throws ConnectionException; + /** + * Returns whether EOF has been received. + */ + boolean isEOF(); + /** * Get the LoggerFactory associated with the SSH client. */ diff --git a/src/main/java/net/schmizz/sshj/sftp/FileMode.java b/src/main/java/net/schmizz/sshj/sftp/FileMode.java index 7ee09c440..e87de80c3 100644 --- a/src/main/java/net/schmizz/sshj/sftp/FileMode.java +++ b/src/main/java/net/schmizz/sshj/sftp/FileMode.java @@ -36,7 +36,7 @@ public static enum Type { /** directory */ DIRECTORY(0040000), /** symbolic link */ - SYMKLINK(0120000), + SYMLINK(0120000), /** unknown */ UNKNOWN(0); diff --git a/src/main/java/net/schmizz/sshj/sftp/Response.java b/src/main/java/net/schmizz/sshj/sftp/Response.java index ff88830a5..a44fac9dd 100644 --- a/src/main/java/net/schmizz/sshj/sftp/Response.java +++ b/src/main/java/net/schmizz/sshj/sftp/Response.java @@ -30,7 +30,30 @@ public static enum StatusCode { BAD_MESSAGE(5), NO_CONNECTION(6), CONNECITON_LOST(7), - OP_UNSUPPORTED(8); + OP_UNSUPPORTED(8), + INVALID_HANDLE(9), + NO_SUCH_PATH(10), + FILE_ALREADY_EXISTS(11), + WRITE_PROTECT(12), + NO_MEDIA(13), + NO_SPACE_ON_FILESYSTEM(14), + QUOTA_EXCEEDED(15), + UNKNOWN_PRINCIPAL(16), + LOCK_CONFLICT(17), + DIR_NOT_EMPTY(18), + NOT_A_DIRECTORY(19), + INVALID_FILENAME(20), + LINK_LOOP(21), + CANNOT_DELETE(22), + INVALID_PARAMETER(23), + FILE_IS_A_DIRECTORY(24), + BYTE_RANGE_LOCK_CONFLICT(25), + BYTE_RANGE_LOCK_REFUSED(26), + DELETE_PENDING(27), + FILE_CORRUPT(28), + OWNER_INVALID(29), + GROUP_INVALID(30), + NO_MATCHING_BYTE_RANGE_LOCK(31); private final int code; diff --git a/src/main/java/net/schmizz/sshj/sftp/SFTPClient.java b/src/main/java/net/schmizz/sshj/sftp/SFTPClient.java index a8539318d..03ae541a3 100644 --- a/src/main/java/net/schmizz/sshj/sftp/SFTPClient.java +++ b/src/main/java/net/schmizz/sshj/sftp/SFTPClient.java @@ -86,7 +86,7 @@ public void mkdir(String dirname) public void mkdirs(String path) throws IOException { - final Deque dirsToMake = new LinkedList<>(); + final Deque dirsToMake = new LinkedList(); for (PathComponents current = engine.getPathHelper().getComponents(path); ; current = engine.getPathHelper().getComponents(current.getParent())) { final FileAttributes attrs = statExistence(current.getPath()); diff --git a/src/main/java/net/schmizz/sshj/sftp/SFTPFileTransfer.java b/src/main/java/net/schmizz/sshj/sftp/SFTPFileTransfer.java index f23314e93..e84094b57 100644 --- a/src/main/java/net/schmizz/sshj/sftp/SFTPFileTransfer.java +++ b/src/main/java/net/schmizz/sshj/sftp/SFTPFileTransfer.java @@ -229,14 +229,36 @@ private String uploadFile(final StreamCopier.Listener listener, final String remote) throws IOException { final String adjusted = prepareFile(local, remote); - try (RemoteFile rf = engine.open(adjusted, EnumSet.of(OpenMode.WRITE, OpenMode.CREAT, OpenMode.TRUNC))) { - try (InputStream fis = local.getInputStream(); - RemoteFile.RemoteFileOutputStream rfos = rf.new RemoteFileOutputStream(0, 16)) { - new StreamCopier(fis, rfos, engine.getLoggerFactory()) - .bufSize(engine.getSubsystem().getRemoteMaxPacketSize() - rf.getOutgoingPacketOverhead()) - .keepFlushing(false) - .listener(listener) - .copy(); + RemoteFile rf = null; + InputStream fis = null; + RemoteFile.RemoteFileOutputStream rfos = null; + try { + rf = engine.open(adjusted, EnumSet.of(OpenMode.WRITE, OpenMode.CREAT, OpenMode.TRUNC)); + fis = local.getInputStream(); + rfos = rf.new RemoteFileOutputStream(0, 16); + new StreamCopier(fis, rfos, engine.getLoggerFactory()) + .bufSize(engine.getSubsystem().getRemoteMaxPacketSize() - rf.getOutgoingPacketOverhead()) + .keepFlushing(false) + .listener(listener) + .copy(); + } finally { + if (rf != null) { + try { + rf.close(); + } catch (IOException e) { + } + } + if (fis != null) { + try { + fis.close(); + } catch (IOException e) { + } + } + if (rfos != null) { + try { + rfos.close(); + } catch (IOException e) { + } } } return adjusted;