2023-09-17 22:13:42 +03:00
package TestingSystem ;
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 ;
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 ) {
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 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 ( ) ) ;
}
}