| 
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -9,6 +9,8 @@ import datetime
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import random
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import hashlib
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import subprocess
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import gzip
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import base64
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import re
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import requests
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import atexit
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -75,6 +77,7 @@ class Gateway():
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    self.nonce_key = None
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    self.stok = None    # HTTP session token
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    self.status = -2
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    self.errcode = -1
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    self.ftp = None
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    self.socket = None  # TCP socket for SSH 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    self.ssh = None     # SSH session
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -898,6 +901,8 @@ class Gateway():
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  def run_cmd(self, command, msg = None, timeout = None, die_on_error = True):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    error = 0
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    reslist = [ ]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    self.errcode = -1
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if self.use_ssh:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        ssh = self.get_ssh(self.verbose)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    else:
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -911,6 +916,8 @@ class Gateway():
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        cmdlist = command
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if not cmdlist:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        raise ValueError('Incorrect command list')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if '\n' in ';'.join(cmdlist):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        raise ValueError('Incorrect command format (1)')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    for idx, cmd in enumerate(cmdlist):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if self.use_ssh:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            channel = ssh.open_session()
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -935,16 +942,41 @@ class Gateway():
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            except Exception:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                pass
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            #status = channel.get_exit_status()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.errcode = 0
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            reslist.append('')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        else: # telnet
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            cmd += '\n'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            tn.write(cmd.encode('ascii'))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            tn.read_until(tn.prompt, timeout = 4 if timeout is None else timeout)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            end = b'echo -e "\\xA6$?\\xA7\\xB8_END"'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            try:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                tn.write(cmd.encode('latin1') + b'\n' + end + b'\n')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                res = tn.read_until(b'\xA7\xB8_END\r\n' + tn.prompt, timeout = 4 if timeout is None else timeout)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                p1 = res.find(b'\r\n')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                p2 = res.rfind(b'\r\n' + tn.prompt + end)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                p3 = res.rfind(b'\r\n\xA6')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                p4 = res.rfind(b'\xA7\xB8_END')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                if p1 < 0 or p2 < 0 or p3 < 0 or p4 < 0 or p3 >= p4:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    if die_on_error:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        die('TELNET: execute command: incorrect response (1)')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    reslist.append(None)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    self.errcode = -2
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    self.errcode = int(res[p3+3:p4].decode(), 10)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    reslist.append(res[p1+2:p2].decode().replace('\r\n', '\n'))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            except Exception as e:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                error = -4
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                if die_on_error:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    die(f'TELNET: execute command error: "{e}"')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if error != 0:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            break
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if not self.use_ssh:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        tn.write(b"exit\n")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        tn.close()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return True if error == 0 else None
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if not self.use_ssh: # telnet
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        try:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            tn.write(b"exit\n")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            tn.close()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        except Exception:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            pass
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if error == 0:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return reslist if isinstance(command, list) else reslist[0]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return None
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  def download(self, fn_remote, fn_local, verbose = 1):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if verbose and self.verbose:
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -965,11 +997,44 @@ class Gateway():
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    read_size += size
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    elif self.use_ftp:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        ftp = self.get_ftp(self.verbose)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        file = open(fn_local, 'wb')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        ftp.retrbinary('RETR ' + fn_remote, file.write)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        file.close()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        raise RuntimeError('FIXME')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        with open(fn_local, 'wb') as file:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            ftp.retrbinary('RETR ' + fn_remote, file.write)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    else: # telnet
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        os.remove(fn_local) if os.path.exists(fn_local) else None
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        size = self.get_remote_file_size(fn_remote)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if size < 0:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            return False
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if size == 0:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            with open(fn_local, 'wb') as file:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                pass
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            return True
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        tn = self.get_telnet(self.verbose)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        fin = b" ; echo 'X''_FIN_''X'"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        blksize = 64*1000
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        filesize = 0
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        with open(fn_local, 'wb') as file:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            while filesize < size:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                count = blksize
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                if filesize + count > size:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    count = size - filesize
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                cmd = f"dd if='{fn_remote}' iflag=skip_bytes,count_bytes skip={filesize} count={count} 2>/dev/null | base64"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                tn.write(cmd.encode('latin1') + fin + b'\n')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                res = tn.read_until(b'X_FIN_X\r\n' + tn.prompt, timeout = 4)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                p1 = res.find(b'\r\n')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                p2 = res.rfind(b'X_FIN_X\r\n')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                if p1 < 0 or p2 < 0 or p1 >= p2:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    break
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                data = base64.standard_b64decode(res[p1+2:p2].replace(b'\r\n', b''))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                filesize += len(data)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                file.write(data)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        try:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            tn.write(b"exit\n")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            tn.close()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        except Exception:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            pass
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if filesize != size:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            os.remove(fn_local) if os.path.exists(fn_local) else None
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            return False
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return True
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  def upload(self, fn_local, fn_remote, md5chk = True, verbose = 1):
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -977,7 +1042,6 @@ class Gateway():
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        die(f'File "{fn_local}" not found.')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if md5chk:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        md5_local = self.get_md5_for_local_file(fn_local)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    file = open(fn_local, 'rb')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if verbose and self.verbose:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        print(f'Upload file: "{fn_local}" ....')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if self.use_ssh:
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -985,17 +1049,48 @@ class Gateway():
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        finfo = os.stat(fn_local)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        channel = ssh.scp_send64(fn_remote, finfo.st_mode & 0o777, finfo.st_size, finfo.st_mtime, finfo.st_atime)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        size = 0
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if True:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        with open(fn_local, 'rb') as file:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            for data in file:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                channel.write(data)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                size = size + len(data)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        #except ssh2.exceptions.SCPProtocolError as e:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    elif self.use_ftp:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        ftp = self.get_ftp(self.verbose)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        ftp.storbinary('STOR ' + fn_remote, file)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        raise RuntimeError('FIXME')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    file.close()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        with open(fn_local, 'rb') as file:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            ftp.storbinary('STOR ' + fn_remote, file)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    else: # telnet
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        with open(fn_local, 'rb') as file:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            data = file.read()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        data = gzip.compress(data, compresslevel = 9)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        data = base64.standard_b64encode(data)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        fn_remote_tmp = '/tmp/_T_' + os.path.basename(fn_remote)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if len(fn_remote_tmp) > 80:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            raise ValueError('Incorrect length of filename')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.run_cmd(f"rm -f '{fn_remote_tmp}'")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        tn = self.get_telnet(self.verbose)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        filesize = 0
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        while filesize < len(data):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            chunk = data[filesize:filesize+400]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if len(chunk) > 0:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                fopt = b'>' if filesize == 0 else b'>>'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                cmd = b"echo -n " + chunk + fopt + fn_remote_tmp.encode()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                tn.write(cmd + b'\n')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                res = tn.read_until(b'\r\n' + tn.prompt, timeout = 4)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                p1 = res.find(b'echo -n ')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                p2 = res.rfind(b'\r\n' + tn.prompt)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                if p1 < 0 or p2 < 0 or p1 >= p2 or p2 - p1 != len(cmd):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    break
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            filesize += len(chunk)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        try:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            tn.write(b"exit\n")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            tn.close()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        except Exception:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            pass
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if filesize != len(data):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.run_cmd(f"rm -f '{fn_remote_tmp}'")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            return False
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.run_cmd(f"rm -f '{fn_remote}' ; cat '{fn_remote_tmp}' | base64 -d | gzip -d > '{fn_remote}'")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.run_cmd(f"rm -f '{fn_remote_tmp}'")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if md5chk:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        md5_remote = self.get_md5_for_remote_file(fn_remote)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if md5_remote != md5_local:
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -1006,6 +1101,12 @@ class Gateway():
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            return False
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return True
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  def get_remote_file_size(self, fn_remote):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    size = self.run_cmd(f"wc -c '{fn_remote}' 2>/dev/null" + " | awk '{print $1}'")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if not size:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return -1
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return int(size, 10)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  def get_md5_for_remote_file(self, fn_remote, timeout = 8):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    fname = os.path.basename(fn_remote)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    num = str(random.randint(10000, 1000000))
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
			
			 | 
			 | 
			
				
 
 |