229 lines
9.3 KiB
Java
229 lines
9.3 KiB
Java
|
|
package TestingSystem;
|
|||
|
|
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 ProjectData.Project.db_project_info;
|
|||
|
|
import Visual_DVM_2021.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<ChannelSftp.LsEntry> 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<String, RemoteFile> remote_subdirs = new LinkedHashMap<>();
|
|||
|
|
LinkedHashMap<String, RemoteFile> remote_files = new LinkedHashMap<>();
|
|||
|
|
Vector<ChannelSftp.LsEntry> 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(db_project_info.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());
|
|||
|
|
}
|
|||
|
|
}
|