sshscp1.java
来自「一个非常好的ssh客户端实现」· Java 代码 · 共 396 行
JAVA
396 行
/****************************************************************************** * * Copyright (c) 1999-2003 AppGate Network Security AB. All Rights Reserved. * * This file contains Original Code and/or Modifications of Original Code as * defined in and that are subject to the MindTerm Public Source License, * Version 2.0, (the 'License'). You may not use this file except in compliance * with the License. * * You should have received a copy of the MindTerm Public Source License * along with this software; see the file LICENSE. If not, write to * AppGate Network Security AB, Otterhallegatan 2, SE-41118 Goteborg, SWEDEN * *****************************************************************************/package com.mindbright.sshcommon;import java.io.InputStream;import java.io.OutputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.File;import java.io.IOException;import java.io.EOFException;public final class SSHSCP1 implements SSHFileTransfer { public final static int DEFAULT_COPY_BUFFER_SZ = 16384; private SSHConsoleRemote remote; private OutputStream out; private InputStream in; private File cwd; private boolean verbose; private SSHFileTransferProgress progress; private byte[] copyBuf; public SSHSCP1(File cwd, SSHConsoleRemote remote, boolean verbose) { this.remote = remote; this.cwd = cwd; this.in = in; this.out = out; this.verbose = verbose; this.copyBuf = new byte[DEFAULT_COPY_BUFFER_SZ]; } public void setProgress(SSHFileTransferProgress progress) { this.progress = progress; } public void abort() { remote.close(); } public void copyToRemote(String localFile, String remoteFile, boolean recursive) throws IOException { File lf = new File(localFile); if(!lf.isAbsolute()) lf = new File(cwd, localFile); if(!lf.exists()) { throw new IOException("File: " + localFile + " does not exist"); } if(!lf.isFile() && !lf.isDirectory()) { throw new IOException("File: " + localFile + " is not a regular file or directory"); } if(lf.isDirectory() && !recursive) { throw new IOException("File: " + localFile + " is a directory, use recursive mode"); } if(remoteFile == null || remoteFile.equals("")) remoteFile = "."; remoteConnect("scp " + (lf.isDirectory() ? "-d " : "") + "-t " + (recursive ? "-r " : "") + (verbose ? "-v " : "") + remoteFile); failsafeReadResponse("After starting remote scp"); writeFileToRemote(lf, recursive); remote.close(); } public void copyToRemote(String[] localFiles, String remoteFile, boolean recursive) throws IOException { if(remoteFile == null || remoteFile.equals("")) remoteFile = "."; if(localFiles.length == 1) { copyToRemote(localFiles[0], remoteFile, recursive); } else { remoteConnect("scp " + "-d -t " + (recursive ? "-r " : "") + (verbose ? "-v " : "") + remoteFile); readResponse("After starting remote scp"); for(int i = 0; i < localFiles.length; i++) { File lf = new File(localFiles[i]); if(!lf.isAbsolute()) lf = new File(cwd, localFiles[i]); if(!lf.isFile() && !lf.isDirectory()) { throw new IOException("File: " + lf.getName() + " is not a regular file or directory"); } writeFileToRemote(lf, recursive); } remote.close(); } } public void copyToLocal(String localFile, String remoteFiles[], boolean recursive) throws IOException { StringBuffer buf = new StringBuffer(); for(int i = 0; i < remoteFiles.length; i++) { buf.append("\""); buf.append(remoteFiles[i]); buf.append("\" "); } String remoteFile = buf.toString(); remoteFile = remoteFile.trim(); copyToLocal(localFile, remoteFile, recursive); } public void copyToLocal(String localFile, String remoteFile, boolean recursive) throws IOException { if(localFile == null || localFile.equals("")) localFile = "."; File lf = new File(localFile); if(!lf.isAbsolute()) lf = new File(cwd, localFile); if(lf.exists() && !lf.isFile() && !lf.isDirectory()) { throw new IOException("File: " + localFile + " is not a regular file or directory"); } remoteConnect("scp " + "-f " + (recursive ? "-r " : "") + (verbose ? "-v " : "") + remoteFile); readFromRemote(lf); remote.close(); } private boolean writeDirToRemote(File dir, boolean recursive) throws IOException { if(!recursive) { writeError("File " + dir.getName() + " is a directory, use recursive mode"); return false; } writeString("D0755 0 " + dir.getName() + "\n"); if(progress != null) progress.startDir(dir.getAbsolutePath()); readResponse("After sedning dirdata"); String[] dirList = dir.list(); for(int i = 0; i < dirList.length; i++) { File f = new File(dir, dirList[i]); writeFileToRemote(f, recursive); } writeString("E\n"); if(progress != null) progress.endDir(); return true; } private void writeFileToRemote(File file, boolean recursive) throws IOException { if(file.isDirectory()) { if(!writeDirToRemote(file, recursive)) return; } else if(file.isFile()) { writeString("C0644 " + file.length() + " " + file.getName() + "\n"); if(progress != null) progress.startFile(file.getName(), file.length()); readResponse("After sending filedata"); FileInputStream fi = new FileInputStream(file); writeFully(fi, file.length()); writeByte(0); if(progress != null) progress.endFile(); } else { throw new IOException("Not ordinary file: " + file.getName()); } readResponse("After writing file"); } private void readFromRemote(File file) throws IOException { String cmd; String[] cmdParts = new String[3]; writeByte(0); while(true) { try { cmd = readString(); } catch (EOFException e) { return; } char cmdChar = cmd.charAt(0); switch(cmdChar) { case 'E': writeByte(0); return; case 'T': throw new IOException("SSHSCP1: (T)ime not supported: " + cmd); case 'C': case 'D': String targetName = file.getAbsolutePath(); parseCommand(cmd, cmdParts); if(file.isDirectory()) { targetName += File.separator + cmdParts[2]; } File targetFile = new File(targetName); if(cmdChar == 'D') { if(targetFile.exists()) { if(!targetFile.isDirectory()) { String msg = "Invalid target " + targetFile.getName() + ", must be a directory"; writeError(msg); throw new IOException(msg); } } else { if(!targetFile.mkdir()) { String msg = "Could not create directory: " + targetFile.getName(); writeError(msg); throw new IOException(msg); } } if(progress != null) progress.startDir(targetFile.getAbsolutePath()); readFromRemote(targetFile); if(progress != null) progress.endDir(); continue; } FileOutputStream fo = new FileOutputStream(targetFile); writeByte(0); long len = Long.parseLong(cmdParts[1]); if(progress != null) progress.startFile(targetFile.getName(), len); readFully(fo, len); readResponse("After reading file"); if(progress != null) progress.endFile(); writeByte(0); break; default: writeError("Unexpected cmd: " + cmd); throw new IOException("Unexpected cmd: " + cmd); } } } private void parseCommand(String cmd, String[] cmdParts) throws IOException { int l, r; l = cmd.indexOf(' '); r = cmd.indexOf(' ', l + 1); if(l == -1 || r == -1) { writeError("Syntax error in cmd"); throw new IOException("Syntax error in cmd"); } cmdParts[0] = cmd.substring(1, l); cmdParts[1] = cmd.substring(l + 1, r); cmdParts[2] = cmd.substring(r + 1); } private void failsafeReadResponse(String where) throws IOException { int r; do { r = readByte(); } while (r >= 10 && r < 127); if(r == 0) { // All is well, no error return; } if(r == -1) { throw new EOFException("SSHSCP1: premature EOF"); } String errMsg = readString(); if(r == (byte)'\02') throw new IOException(errMsg); throw new IOException("SSHSCP1.readResponse, error: " + errMsg); } private void readResponse(String where) throws IOException { int r = readByte(); if(r == 0) { // All is well, no error return; } if(r == -1) { throw new EOFException("SSHSCP1: premature EOF"); } String errMsg = readString(); if(r == (byte)'\02') throw new IOException(errMsg); throw new IOException("SSHSCP1.readResponse, error: " + errMsg); } private void writeError(String reason) throws IOException { writeByte(1); writeString(reason); } private int readByte() throws IOException { return in.read(); } private String readString() throws IOException { int ch, i = 0; while(((ch = readByte()) != ((int)'\n')) && ch >= 0) { copyBuf[i++] = (byte)ch; } if(ch == -1) { throw new EOFException("SSHSCP1: premature EOF"); } if(copyBuf[0] == (byte)'\n') throw new IOException("Unexpected <NL>"); if(copyBuf[0] == (byte)'\02' || copyBuf[0] == (byte)'\01') { String errMsg = new String(copyBuf, 1, i - 1); if(copyBuf[0] == (byte)'\02') throw new IOException(errMsg); throw new IOException("SSHSCP.readString, error: " + errMsg); } return new String(copyBuf, 0, i); } private void readFully(FileOutputStream file, long size) throws IOException { long cnt = 0, n; try { while(cnt < size) { n = (long)in.read(copyBuf, 0, (int) ((size - cnt) < DEFAULT_COPY_BUFFER_SZ ? (size - cnt) : DEFAULT_COPY_BUFFER_SZ)); if(n == -1) { throw new EOFException("SSHSCP1: premature EOF"); } cnt += n; file.write(copyBuf, 0, (int)n); if(progress != null) progress.progress((int)n); } } finally { file.close(); } } private void writeByte(int b) throws IOException { out.write(b); } private void writeString(String str) throws IOException { byte[] buf = str.getBytes(); out.write(buf); } private void writeFully(FileInputStream file, long size) throws IOException { long cnt = 0, n; try { while(cnt < size) { n = (int)file.read(copyBuf, 0, (int) ((size - cnt) < DEFAULT_COPY_BUFFER_SZ ? (size - cnt) : DEFAULT_COPY_BUFFER_SZ)); if(n == -1) { throw new EOFException("SSHSCP1: premature EOF"); } cnt += n; out.write(copyBuf, 0, (int)n); if(progress != null) progress.progress((int)n); } } finally { file.close(); } } private void remoteConnect(String command) throws IOException { if(!remote.command(command)) { throw new IOException("SSHSCP.remoteConnect, failed to run: " + command); } this.in = remote.getStdOut(); this.out = remote.getStdIn(); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?