2023-11-19 02:12:44 +03:00
package TestingSystem.DVM ;
2023-10-06 22:51:09 +03:00
import Common.Constants ;
2023-09-17 22:13:42 +03:00
import Common.Global ;
import Common.Utils.Utils ;
import Common.Utils.Validators.ShellParser ;
import GlobalData.Machine.Machine ;
import GlobalData.RemoteFile.RemoteFile ;
import GlobalData.User.User ;
2023-11-19 02:12:44 +03:00
import Visual_DVM_2021.Passes.PassException ;
2023-12-04 14:42:36 +03:00
import com.jcraft.jsch.* ;
2023-12-04 20:40:44 +03:00
import javafx.util.Pair ;
2023-09-17 22:13:42 +03:00
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 ( ) ;
}
//--
2023-12-04 14:42:36 +03:00
//todo из за мусора результатом пользоваться в общем случае невозможно.
//следует перенаправлять вывод в какой нибудь временный файл на сервере.
2023-09-17 22:13:42 +03:00
public String ShellCommand ( String command ) throws Exception {
StringBuilder result = new StringBuilder ( ) ;
pin . write ( ( command + " \ r \ n " ) . getBytes ( ) ) ;
ShellParser . ReadInvitation ( fromServer ) ; //первое приглашение после эхо. возможен мусор.
result . append ( ShellParser . getCommandResult ( fromServer ) ) ; //возможный результат и второе приглашение.
String [ ] data = result . toString ( ) . split ( " \ n " ) ;
return ( data . length > 0 ) ? data [ data . length - 1 ] : result . toString ( ) ;
}
public void getSingleFile ( String src , String dst ) throws Exception {
sftpChannel . get ( src , dst ) ;
}
2023-12-04 14:42:36 +03:00
public long getFileKBSize ( String path ) throws Exception {
2023-09-17 22:13:42 +03:00
long size = sftpChannel . lstat ( path ) . getSize ( ) ;
2023-12-04 14:42:36 +03:00
return size / 1024 ;
2023-09-17 22:13:42 +03:00
}
2023-12-04 14:42:36 +03:00
public void getSingleFileWithMaxSize ( RemoteFile src , File dst , int maxSize ) throws Exception {
if ( ( maxSize = = 0 ) | | getFileKBSize ( src . full_name ) < = maxSize ) {
getSingleFile ( src . full_name , dst . getAbsolutePath ( ) ) ;
} else {
Utils . WriteToFile ( dst , " Размер файла превышает " + maxSize + " KB. \ n " + " Файл не загружен. Е г о можно просмотреть на машине по адресу \ n " + Utils . Brackets ( src . full_name ) ) ;
2023-09-17 22:13:42 +03:00
}
}
public void putSingleFile ( File src , RemoteFile dst ) throws Exception {
sftpChannel . put ( src . getAbsolutePath ( ) , dst . full_name ) ;
}
//-
public void MKDIR ( RemoteFile dir ) throws Exception {
2023-12-04 14:42:36 +03:00
if ( ! Exists ( dir ) ) sftpChannel . mkdir ( dir . full_name ) ;
2023-09-17 22:13:42 +03:00
}
//-
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 ) {
2023-10-06 22:51:09 +03:00
if ( ! lsd . getName ( ) . equals ( Constants . data ) ) {
2023-09-17 22:13:42 +03:00
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 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 ( ) ) ;
}
2023-12-04 14:42:36 +03:00
//--
public boolean Exists ( String file_full_name ) throws Exception {
try {
sftpChannel . lstat ( file_full_name ) ;
return true ;
} catch ( SftpException e ) {
if ( e . id = = ChannelSftp . SSH_FX_NO_SUCH_FILE ) {
// file doesn't exist
return false ;
} else {
// something else went wrong
throw e ;
}
}
}
public boolean Exists ( RemoteFile file ) throws Exception {
return Exists ( file . full_name ) ;
}
2023-12-04 20:40:44 +03:00
//--
public Pair < RemoteFile , RemoteFile > performScript ( RemoteFile directory , String . . . commands ) throws Exception {
RemoteFile script_file = new RemoteFile ( directory , Constants . script ) ;
RemoteFile out = new RemoteFile ( directory , Constants . out_file ) ;
RemoteFile err = new RemoteFile ( directory , Constants . err_file ) ;
//
Vector < RemoteFile > files = new Vector < > ( ) ;
files . add ( script_file ) ;
files . add ( out ) ;
files . add ( err ) ;
for ( RemoteFile file : files ) {
if ( Exists ( file ) )
sftpChannel . rm ( file . full_name ) ;
}
//--
writeToFile ( " cd " + Utils . DQuotes ( directory . full_name ) + " \ n " + String . join ( " \ n " , commands ) , script_file ) ;
//--
ShellCommand ( script_file . full_name + " 1> " + Utils . DQuotes ( out . full_name ) + " 2> " + Utils . DQuotes ( err . full_name ) ) ;
return new Pair < > ( out , err ) ;
}
2023-09-17 22:13:42 +03:00
}