package Repository.TestingSystem.DVM; import Common.Constants; import Common.Global; import Common.Utils.Utils; import Common.Utils.Validators.ShellParser; import GlobalData.Machine.Machine; import GlobalData.RemoteFile.RemoteFile; import GlobalData.User.User; import Common.Passes.PassException; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.ChannelShell; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import java.io.*; import java.nio.charset.StandardCharsets; import java.util.LinkedHashMap; import java.util.Vector; public class UserConnection { public ChannelSftp sftpChannel = null; public ChannelShell shellChannel = null; //-- JSch jsch = null; Session session = null; //--- PipedInputStream in = null; PipedOutputStream out = null; //--- PipedOutputStream pin = null; PipedInputStream pout = null; InputStreamReader fromServer = null; //--- public UserConnection(Machine machine, User user) throws Exception { session = (jsch = new JSch()).getSession(user.login, machine.address, machine.port); session.setPassword(user.password); session.setConfig("StrictHostKeyChecking", "no"); session.connect(0); //--> //создать канал для файлов sftpChannel = (ChannelSftp) session.openChannel("sftp"); sftpChannel.connect(); //--> //создать канал для команд shellChannel = (ChannelShell) session.openChannel("shell"); in = new PipedInputStream(); out = new PipedOutputStream(); shellChannel.setInputStream(in); shellChannel.setOutputStream(out); pin = new PipedOutputStream(in); pout = new PipedInputStream(out); shellChannel.connect(); //- fromServer = new InputStreamReader(pout); ShellParser.setUserName(user.login); ShellParser.ReadInvitation(fromServer); //прочитать первое приглашение от машины. } public void Disconnect() { if (in != null) { try { in.close(); } catch (Exception exception) { Global.Log.PrintException(exception); } } if (out != null) { try { out.close(); } catch (Exception exception) { Global.Log.PrintException(exception); } } if (pin != null) { try { pin.close(); } catch (Exception exception) { Global.Log.PrintException(exception); } } if (pout != null) { try { pout.close(); } catch (Exception exception) { Global.Log.PrintException(exception); } } if (fromServer != null) { try { fromServer.close(); } catch (Exception exception) { Global.Log.PrintException(exception); } } if (sftpChannel != null) sftpChannel.disconnect(); if (shellChannel != null) shellChannel.disconnect(); if (session != null) session.disconnect(); //---------------------- sftpChannel = null; shellChannel = null; jsch = null; session = null; //--- in = null; out = null; //--- pin = null; pout = null; fromServer = null; System.gc(); } //-- //из за мусора результатом пользоваться в общем случае невозможно. public String ShellCommand(String command) throws Exception { StringBuilder result = new StringBuilder(); // System.out.println("command=" + Utils.Brackets(command)); pin.write((command + "\r\n").getBytes()); ShellParser.ReadInvitation(fromServer); //первое приглашение после эхо. возможен мусор. result.append(ShellParser.getCommandResult(fromServer)); //возможный результат и второе приглашение. // System.out.println("answer=" + Utils.Brackets(result)); //в реалиях визуалиазтора нас интересует только ПОСЛЕДНЯЯ СТРОКА ОТВЕТА. String[] data = result.toString().split("\n"); // System.out.println("res="+Utils.Brackets(res)); return (data.length > 0) ? data[data.length - 1] : result.toString(); } //-- //тут имя файла короткое. public boolean Exists(String folder, String name) throws Exception { Vector files = sftpChannel.ls(folder); for (ChannelSftp.LsEntry file : files) { file.getAttrs().getSize(); if (file.getFilename().equals(name)) { return true; } } return false; } //-- public void getSingleFile(String src, String dst) throws Exception { sftpChannel.get(src, dst); } public long getFileKBSize(String path) throws Exception{ long size = sftpChannel.lstat(path).getSize(); return size/1024; } public boolean getSingleFile(RemoteFile src, File dst, int maxSize) throws Exception { if (Exists(src.parent, src.name)) { if ((maxSize == 0) || getFileKBSize(src.full_name) <= maxSize) { getSingleFile(src.full_name, dst.getAbsolutePath()); return true; } else { Utils.WriteToFile(dst, "Размер файла превышает " + maxSize + " KB.\n" + "Файл не загружен. Его можно просмотреть на машине по адресу\n" + Utils.Brackets(src.full_name)); } } return false; } public void putSingleFile(File src, RemoteFile dst) throws Exception { sftpChannel.put(src.getAbsolutePath(), dst.full_name); } //- public void MKDIR(RemoteFile dir) throws Exception { if (!Exists(dir.parent, dir.name)) sftpChannel.mkdir(dir.full_name); } //- public void RMDIR(String dir) throws Exception { if (!dir.isEmpty() && !dir.equals("/") && !dir.equals("\\") && !dir.equals("*")) { ShellCommand("rm -rf " + Utils.DQuotes(dir)); } else throw new PassException("Недопустимый путь для удаления папки " + Utils.DQuotes(dir)); } //- public void SynchronizeSubDirsR(File local_dir, RemoteFile remote_dir) throws Exception { File[] local_subdirs = local_dir.listFiles(File::isDirectory); File[] local_files = local_dir.listFiles(File::isFile); //------------------------------------------------------------------------ LinkedHashMap remote_subdirs = new LinkedHashMap<>(); LinkedHashMap remote_files = new LinkedHashMap<>(); Vector files = sftpChannel.ls(remote_dir.full_name); for (ChannelSftp.LsEntry file : files) { if (file.getAttrs().isDir()) { if (!file.getFilename().equals(".") && !file.getFilename().equals("..")) remote_subdirs.put(file.getFilename(), new RemoteFile(remote_dir.full_name, file.getFilename(), true)); } else { RemoteFile rf = new RemoteFile(remote_dir.full_name, file.getFilename()); rf.updateTime = RemoteFile.convertUpdateTime(file.getAttrs().getMTime()); remote_files.put(file.getFilename(), rf); } } if (local_subdirs != null) { for (File lsd : local_subdirs) { if (!lsd.getName().equals(Constants.data)) { RemoteFile rsd = null; if (!remote_subdirs.containsKey(lsd.getName())) sftpChannel.mkdir((rsd = new RemoteFile(remote_dir.full_name, lsd.getName(), true)).full_name); else rsd = remote_subdirs.get(lsd.getName()); SynchronizeSubDirsR(lsd, rsd); } } } if (local_files != null) { for (File lf : local_files) { RemoteFile rf = null; if (!remote_files.containsKey(lf.getName())) { rf = new RemoteFile(remote_dir.full_name, lf.getName()); putSingleFile(lf, rf); } else { rf = remote_files.get(lf.getName()); if (lf.lastModified() > rf.updateTime) { putSingleFile(lf, rf); } } } } } /* public void copy(RemoteFile src, RemoteFile dst) throws Exception { ShellCommand("cp " + Utils.DQuotes(src.full_name) + " " + Utils.DQuotes(dst.full_name)); } */ //------- public void writeToFile(String text, RemoteFile dst) throws Exception { sftpChannel.put(new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8)), dst.full_name); sftpChannel.chmod(0777, dst.full_name); } public String readFromFile(RemoteFile src) throws Exception { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); sftpChannel.get(src.full_name, outputStream); return outputStream.toString(StandardCharsets.UTF_8.name()); } }