diff options
Diffstat (limited to 'lldb/third_party/Python/module/pexpect-4.6/examples/cgishell.cgi')
-rwxr-xr-x | lldb/third_party/Python/module/pexpect-4.6/examples/cgishell.cgi | 766 |
1 files changed, 0 insertions, 766 deletions
diff --git a/lldb/third_party/Python/module/pexpect-4.6/examples/cgishell.cgi b/lldb/third_party/Python/module/pexpect-4.6/examples/cgishell.cgi deleted file mode 100755 index 57d8667eb91..00000000000 --- a/lldb/third_party/Python/module/pexpect-4.6/examples/cgishell.cgi +++ /dev/null @@ -1,766 +0,0 @@ -#!/usr/bin/python -##!/usr/bin/env python -"""CGI shell server - -This exposes a shell terminal on a web page. -It uses AJAX to send keys and receive screen updates. -The client web browser needs nothing but CSS and Javascript. - - --hostname : sets the remote host name to open an ssh connection to. - --username : sets the user name to login with - --password : (optional) sets the password to login with - --port : set the local port for the server to listen on - --watch : show the virtual screen after each client request - -This project is probably not the most security conscious thing I've ever built. -This should be considered an experimental tool -- at best. -""" - -from __future__ import absolute_import -from __future__ import print_function - -import sys,os -sys.path.insert (0,os.getcwd()) # let local modules precede any installed modules -import socket, random, string, traceback, cgi, time, getopt, getpass, threading, resource, signal -import pxssh, pexpect, ANSI - -def exit_with_usage(exit_code=1): - print(globals()['__doc__']) - os._exit(exit_code) - -def client (command, host='localhost', port=-1): - """This sends a request to the server and returns the response. - If port <= 0 then host is assumed to be the filename of a Unix domain socket. - If port > 0 then host is an inet hostname. - """ - if port <= 0: - s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - s.connect(host) - else: - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.connect((host, port)) - s.send(command) - data = s.recv (2500) - s.close() - return data - -def server (hostname, username, password, socket_filename='/tmp/server_sock', daemon_mode = True, verbose=False): - """This starts and services requests from a client. - If daemon_mode is True then this forks off a separate daemon process and returns the daemon's pid. - If daemon_mode is False then this does not return until the server is done. - """ - if daemon_mode: - mypid_name = '/tmp/%d.pid' % os.getpid() - daemon_pid = daemonize(daemon_pid_filename=mypid_name) - time.sleep(1) - if daemon_pid != 0: - os.unlink(mypid_name) - return daemon_pid - - virtual_screen = ANSI.ANSI (24,80) - child = pxssh.pxssh() - try: - child.login (hostname, username, password, login_naked=True) - except: - return - if verbose: print('login OK') - virtual_screen.write (child.before) - virtual_screen.write (child.after) - - if os.path.exists(socket_filename): os.remove(socket_filename) - s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - s.bind(socket_filename) - os.chmod(socket_filename, 0o777) - if verbose: print('Listen') - s.listen(1) - - r = roller (endless_poll, (child, child.PROMPT, virtual_screen)) - r.start() - if verbose: print("started screen-poll-updater in background thread") - sys.stdout.flush() - try: - while True: - conn, addr = s.accept() - if verbose: print('Connected by', addr) - data = conn.recv(1024) - request = data.split(' ', 1) - if len(request)>1: - cmd = request[0].strip() - arg = request[1].strip() - else: - cmd = request[0].strip() - arg = '' - - if cmd == 'exit': - r.cancel() - break - elif cmd == 'sendline': - child.sendline (arg) - time.sleep(0.1) - shell_window = str(virtual_screen) - elif cmd == 'send' or cmd=='xsend': - if cmd=='xsend': - arg = arg.decode("hex") - child.send (arg) - time.sleep(0.1) - shell_window = str(virtual_screen) - elif cmd == 'cursor': - shell_window = '%x,%x' % (virtual_screen.cur_r, virtual_screen.cur_c) - elif cmd == 'refresh': - shell_window = str(virtual_screen) - elif cmd == 'hash': - shell_window = str(hash(str(virtual_screen))) - - response = [] - response.append (shell_window) - if verbose: print('\n'.join(response)) - sent = conn.send('\n'.join(response)) - if sent < len (response): - if verbose: print("Sent is too short. Some data was cut off.") - conn.close() - except e: - pass - r.cancel() - if verbose: print("cleaning up socket") - s.close() - if os.path.exists(socket_filename): os.remove(socket_filename) - if verbose: print("server done!") - -class roller (threading.Thread): - """This class continuously loops a function in a thread. - This is basically a thin layer around Thread with a - while loop and a cancel. - """ - def __init__(self, function, args=[], kwargs={}): - threading.Thread.__init__(self) - self.function = function - self.args = args - self.kwargs = kwargs - self.finished = threading.Event() - def cancel(self): - """Stop the roller.""" - self.finished.set() - def run(self): - while not self.finished.isSet(): - self.function(*self.args, **self.kwargs) - -def endless_poll (child, prompt, screen, refresh_timeout=0.1): - """This keeps the screen updated with the output of the child. - This will be run in a separate thread. See roller class. - """ - #child.logfile_read = screen - try: - s = child.read_nonblocking(4000, 0.1) - screen.write(s) - except: - pass - -def daemonize (stdin=None, stdout=None, stderr=None, daemon_pid_filename=None): - """This runs the current process in the background as a daemon. - The arguments stdin, stdout, stderr allow you to set the filename that the daemon reads and writes to. - If they are set to None then all stdio for the daemon will be directed to /dev/null. - If daemon_pid_filename is set then the pid of the daemon will be written to it as plain text - and the pid will be returned. If daemon_pid_filename is None then this will return None. - """ - UMASK = 0 - WORKINGDIR = "/" - MAXFD = 1024 - - # The stdio file descriptors are redirected to /dev/null by default. - if hasattr(os, "devnull"): - DEVNULL = os.devnull - else: - DEVNULL = "/dev/null" - if stdin is None: stdin = DEVNULL - if stdout is None: stdout = DEVNULL - if stderr is None: stderr = DEVNULL - - try: - pid = os.fork() # fork first child - except OSError as e: - raise Exception("%s [%d]" % (e.strerror, e.errno)) - - if pid != 0: - os.waitpid(pid,0) - if daemon_pid_filename is not None: - daemon_pid = int(file(daemon_pid_filename,'r').read()) - return daemon_pid - else: - return None - - # first child - os.setsid() - signal.signal(signal.SIGHUP, signal.SIG_IGN) - - try: - pid = os.fork() # fork second child - except OSError as e: - raise Exception("%s [%d]" % (e.strerror, e.errno)) - - if pid != 0: - if daemon_pid_filename is not None: - file(daemon_pid_filename,'w').write(str(pid)) - os._exit(0) # exit parent (the first child) of the second child. - - # second child - os.chdir(WORKINGDIR) - os.umask(UMASK) - - maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1] - if maxfd == resource.RLIM_INFINITY: - maxfd = MAXFD - - # close all file descriptors - for fd in range(0, maxfd): - try: - os.close(fd) - except OSError: # fd wasn't open to begin with (ignored) - pass - - os.open (DEVNULL, os.O_RDWR) # standard input - - # redirect standard file descriptors - si = open(stdin, 'r') - so = open(stdout, 'a+') - se = open(stderr, 'a+', 0) - os.dup2(si.fileno(), sys.stdin.fileno()) - os.dup2(so.fileno(), sys.stdout.fileno()) - os.dup2(se.fileno(), sys.stderr.fileno()) - - return 0 - -def client_cgi (): - """This handles the request if this script was called as a cgi. - """ - sys.stderr = sys.stdout - ajax_mode = False - TITLE="Shell" - SHELL_OUTPUT="" - SID="NOT" - print("Content-type: text/html;charset=utf-8\r\n") - try: - form = cgi.FieldStorage() - if 'ajax' in form: - ajax_mode = True - ajax_cmd = form['ajax'].value - SID=form['sid'].value - if ajax_cmd == 'send': - command = 'xsend' - arg = form['arg'].value.encode('hex') - result = client (command + ' ' + arg, '/tmp/'+SID) - print(result) - elif ajax_cmd == 'refresh': - command = 'refresh' - result = client (command, '/tmp/'+SID) - print(result) - elif ajax_cmd == 'cursor': - command = 'cursor' - result = client (command, '/tmp/'+SID) - print(result) - elif ajax_cmd == 'exit': - command = 'exit' - result = client (command, '/tmp/'+SID) - print(result) - elif ajax_cmd == 'hash': - command = 'hash' - result = client (command, '/tmp/'+SID) - print(result) - elif 'sid' not in form: - SID=random_sid() - print(LOGIN_HTML % locals()); - else: - SID=form['sid'].value - if 'start_server' in form: - USERNAME = form['username'].value - PASSWORD = form['password'].value - dpid = server ('127.0.0.1', USERNAME, PASSWORD, '/tmp/'+SID) - SHELL_OUTPUT="daemon pid: " + str(dpid) - else: - if 'cli' in form: - command = 'sendline ' + form['cli'].value - else: - command = 'sendline' - SHELL_OUTPUT = client (command, '/tmp/'+SID) - print(CGISH_HTML % locals()) - except: - tb_dump = traceback.format_exc() - if ajax_mode: - print(str(tb_dump)) - else: - SHELL_OUTPUT=str(tb_dump) - print(CGISH_HTML % locals()) - -def server_cli(): - """This is the command line interface to starting the server. - This handles things if the script was not called as a CGI - (if you run it from the command line). - """ - try: - optlist, args = getopt.getopt(sys.argv[1:], 'h?d', ['help','h','?', 'hostname=', 'username=', 'password=', 'port=', 'watch']) - except Exception as e: - print(str(e)) - exit_with_usage() - - command_line_options = dict(optlist) - options = dict(optlist) - # There are a million ways to cry for help. These are but a few of them. - if [elem for elem in command_line_options if elem in ['-h','--h','-?','--?','--help']]: - exit_with_usage(0) - - hostname = "127.0.0.1" - #port = 1664 - username = os.getenv('USER') - password = "" - daemon_mode = False - if '-d' in options: - daemon_mode = True - if '--watch' in options: - watch_mode = True - else: - watch_mode = False - if '--hostname' in options: - hostname = options['--hostname'] - if '--port' in options: - port = int(options['--port']) - if '--username' in options: - username = options['--username'] - if '--password' in options: - password = options['--password'] - else: - password = getpass.getpass('password: ') - - server (hostname, username, password, '/tmp/mysock', daemon_mode) - -def random_sid (): - a=random.randint(0,65535) - b=random.randint(0,65535) - return '%04x%04x.sid' % (a,b) - -def parse_host_connect_string (hcs): - """This parses a host connection string in the form - username:password@hostname:port. All fields are options expcet hostname. A - dictionary is returned with all four keys. Keys that were not included are - set to empty strings ''. Note that if your password has the '@' character - then you must backslash escape it. - """ - if '@' in hcs: - p = re.compile (r'(?P<username>[^@:]*)(:?)(?P<password>.*)(?!\\)@(?P<hostname>[^:]*):?(?P<port>[0-9]*)') - else: - p = re.compile (r'(?P<username>)(?P<password>)(?P<hostname>[^:]*):?(?P<port>[0-9]*)') - m = p.search (hcs) - d = m.groupdict() - d['password'] = d['password'].replace('\\@','@') - return d - -def pretty_box (s, rows=24, cols=80): - """This puts an ASCII text box around the given string. - """ - top_bot = '+' + '-'*cols + '+\n' - return top_bot + '\n'.join(['|'+line+'|' for line in s.split('\n')]) + '\n' + top_bot - -def main (): - if os.getenv('REQUEST_METHOD') is None: - server_cli() - else: - client_cgi() - -# It's mostly HTML and Javascript from here on out. -CGISH_HTML="""<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<html> -<head> -<title>%(TITLE)s %(SID)s</title> -<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> -<style type=text/css> -a {color: #9f9; text-decoration: none} -a:hover {color: #0f0} -hr {color: #0f0} -html,body,textarea,input,form -{ -font-family: "Courier New", Courier, mono; -font-size: 8pt; -color: #0c0; -background-color: #020; -margin:0; -padding:0; -border:0; -} -input { background-color: #010; } -textarea { -border-width:1; -border-style:solid; -border-color:#0c0; -padding:3; -margin:3; -} -</style> - -<script language="JavaScript"> -function focus_first() -{if (document.forms.length > 0) -{var TForm = document.forms[0]; -for (i=0;i<TForm.length;i++){ -if ((TForm.elements[i].type=="text")|| -(TForm.elements[i].type=="textarea")|| -(TForm.elements[i].type.toString().charAt(0)=="s")) -{document.forms[0].elements[i].focus();break;}}}} - -// JavaScript Virtual Keyboard -// If you like this code then buy me a sandwich. -// Noah Spurrier <noah@noah.org> -var flag_shift=0; -var flag_shiftlock=0; -var flag_ctrl=0; -var ButtonOnColor="#ee0"; - -function init () -{ - // hack to set quote key to show both single quote and double quote - document.form['quote'].value = "'" + ' "'; - //refresh_screen(); - poll(); - document.form["cli"].focus(); -} -function get_password () -{ - var username = prompt("username?",""); - var password = prompt("password?",""); - start_server (username, password); -} -function multibrowser_ajax () -{ - var xmlHttp = false; -/*@cc_on @*/ -/*@if (@_jscript_version >= 5) - try - { - xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); - } - catch (e) - { - try - { - xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); - } - catch (e2) - { - xmlHttp = false; - } - } -@end @*/ - - if (!xmlHttp && typeof XMLHttpRequest != 'undefined') - { - xmlHttp = new XMLHttpRequest(); - } - return xmlHttp; -} -function load_url_to_screen(url) -{ - xmlhttp = multibrowser_ajax(); - //window.XMLHttpRequest?new XMLHttpRequest(): new ActiveXObject("Microsoft.XMLHTTP"); - xmlhttp.onreadystatechange = update_virtual_screen; - xmlhttp.open("GET", url); - xmlhttp.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"); - xmlhttp.send(null); -} -function update_virtual_screen() -{ - if ((xmlhttp.readyState == 4) && (xmlhttp.status == 200)) - { - var screen_text = xmlhttp.responseText; - document.form["screen_text"].value = screen_text; - //var json_data = json_parse(xmlhttp.responseText); - } -} -function poll() -{ - refresh_screen(); - timerID = setTimeout("poll()", 2000); - // clearTimeout(timerID); -} -//function start_server (username, password) -//{ -// load_url_to_screen('cgishell.cgi?ajax=serverstart&username=' + escape(username) + '&password=' + escape(password); -//} -function refresh_screen() -{ - load_url_to_screen('cgishell.cgi?ajax=refresh&sid=%(SID)s'); -} -function query_hash() -{ - load_url_to_screen('cgishell.cgi?ajax=hash&sid=%(SID)s'); -} -function query_cursor() -{ - load_url_to_screen('cgishell.cgi?ajax=cursor&sid=%(SID)s'); -} -function exit_server() -{ - load_url_to_screen('cgishell.cgi?ajax=exit&sid=%(SID)s'); -} -function type_key (chars) -{ - var ch = '?'; - if (flag_shiftlock || flag_shift) - { - ch = chars.substr(1,1); - } - else if (flag_ctrl) - { - ch = chars.substr(2,1); - } - else - { - ch = chars.substr(0,1); - } - load_url_to_screen('cgishell.cgi?ajax=send&sid=%(SID)s&arg=' + escape(ch)); - if (flag_shift || flag_ctrl) - { - flag_shift = 0; - flag_ctrl = 0; - } - update_button_colors(); -} - -function key_shiftlock() -{ - flag_ctrl = 0; - flag_shift = 0; - if (flag_shiftlock) - { - flag_shiftlock = 0; - } - else - { - flag_shiftlock = 1; - } - update_button_colors(); -} - -function key_shift() -{ - if (flag_shift) - { - flag_shift = 0; - } - else - { - flag_ctrl = 0; - flag_shiftlock = 0; - flag_shift = 1; - } - update_button_colors(); -} -function key_ctrl () -{ - if (flag_ctrl) - { - flag_ctrl = 0; - } - else - { - flag_ctrl = 1; - flag_shiftlock = 0; - flag_shift = 0; - } - - update_button_colors(); -} -function update_button_colors () -{ - if (flag_ctrl) - { - document.form['Ctrl'].style.backgroundColor = ButtonOnColor; - document.form['Ctrl2'].style.backgroundColor = ButtonOnColor; - } - else - { - document.form['Ctrl'].style.backgroundColor = document.form.style.backgroundColor; - document.form['Ctrl2'].style.backgroundColor = document.form.style.backgroundColor; - } - if (flag_shift) - { - document.form['Shift'].style.backgroundColor = ButtonOnColor; - document.form['Shift2'].style.backgroundColor = ButtonOnColor; - } - else - { - document.form['Shift'].style.backgroundColor = document.form.style.backgroundColor; - document.form['Shift2'].style.backgroundColor = document.form.style.backgroundColor; - } - if (flag_shiftlock) - { - document.form['ShiftLock'].style.backgroundColor = ButtonOnColor; - } - else - { - document.form['ShiftLock'].style.backgroundColor = document.form.style.backgroundColor; - } - -} -function keyHandler(e) -{ - var pressedKey; - if (document.all) { e = window.event; } - if (document.layers) { pressedKey = e.which; } - if (document.all) { pressedKey = e.keyCode; } - pressedCharacter = String.fromCharCode(pressedKey); - type_key(pressedCharacter+pressedCharacter+pressedCharacter); - alert(pressedCharacter); -// alert(' Character = ' + pressedCharacter + ' [Decimal value = ' + pressedKey + ']'); -} -//document.onkeypress = keyHandler; -//if (document.layers) -// document.captureEvents(Event.KEYPRESS); -//http://sniptools.com/jskeys -//document.onkeyup = KeyCheck; -function KeyCheck(e) -{ - var KeyID = (window.event) ? event.keyCode : e.keyCode; - type_key(String.fromCharCode(KeyID)); - e.cancelBubble = true; - window.event.cancelBubble = true; -} -</script> - -</head> - -<body onload="init()"> -<form id="form" name="form" action="/cgi-bin/cgishell.cgi" method="POST"> -<input name="sid" value="%(SID)s" type="hidden"> -<textarea name="screen_text" cols="81" rows="25">%(SHELL_OUTPUT)s</textarea> -<hr noshade="1"> - <input name="cli" id="cli" type="text" size="80"><br> -<table border="0" align="left"> -<tr> -<td width="86%%" align="center"> - <input name="submit" type="submit" value="Submit"> - <input name="refresh" type="button" value="REFRESH" onclick="refresh_screen()"> - <input name="refresh" type="button" value="CURSOR" onclick="query_cursor()"> - <input name="hash" type="button" value="HASH" onclick="query_hash()"> - <input name="exit" type="button" value="EXIT" onclick="exit_server()"> - <br> - <input type="button" value="Esc" onclick="type_key('\\x1b\\x1b')" /> - <input type="button" value="` ~" onclick="type_key('`~')" /> - <input type="button" value="1!" onclick="type_key('1!')" /> - <input type="button" value="2@" onclick="type_key('2@\\x00')" /> - <input type="button" value="3#" onclick="type_key('3#')" /> - <input type="button" value="4$" onclick="type_key('4$')" /> - <input type="button" value="5%%" onclick="type_key('5%%')" /> - <input type="button" value="6^" onclick="type_key('6^\\x1E')" /> - <input type="button" value="7&" onclick="type_key('7&')" /> - <input type="button" value="8*" onclick="type_key('8*')" /> - <input type="button" value="9(" onclick="type_key('9(')" /> - <input type="button" value="0)" onclick="type_key('0)')" /> - <input type="button" value="-_" onclick="type_key('-_\\x1F')" /> - <input type="button" value="=+" onclick="type_key('=+')" /> - <input type="button" value="BkSp" onclick="type_key('\\x08\\x08\\x08')" /> - <br> - <input type="button" value="Tab" onclick="type_key('\\t\\t')" /> - <input type="button" value="Q" onclick="type_key('qQ\\x11')" /> - <input type="button" value="W" onclick="type_key('wW\\x17')" /> - <input type="button" value="E" onclick="type_key('eE\\x05')" /> - <input type="button" value="R" onclick="type_key('rR\\x12')" /> - <input type="button" value="T" onclick="type_key('tT\\x14')" /> - <input type="button" value="Y" onclick="type_key('yY\\x19')" /> - <input type="button" value="U" onclick="type_key('uU\\x15')" /> - <input type="button" value="I" onclick="type_key('iI\\x09')" /> - <input type="button" value="O" onclick="type_key('oO\\x0F')" /> - <input type="button" value="P" onclick="type_key('pP\\x10')" /> - <input type="button" value="[ {" onclick="type_key('[{\\x1b')" /> - <input type="button" value="] }" onclick="type_key(']}\\x1d')" /> - <input type="button" value="\\ |" onclick="type_key('\\\\|\\x1c')" /> - <br> - <input type="button" id="Ctrl" value="Ctrl" onclick="key_ctrl()" /> - <input type="button" value="A" onclick="type_key('aA\\x01')" /> - <input type="button" value="S" onclick="type_key('sS\\x13')" /> - <input type="button" value="D" onclick="type_key('dD\\x04')" /> - <input type="button" value="F" onclick="type_key('fF\\x06')" /> - <input type="button" value="G" onclick="type_key('gG\\x07')" /> - <input type="button" value="H" onclick="type_key('hH\\x08')" /> - <input type="button" value="J" onclick="type_key('jJ\\x0A')" /> - <input type="button" value="K" onclick="type_key('kK\\x0B')" /> - <input type="button" value="L" onclick="type_key('lL\\x0C')" /> - <input type="button" value="; :" onclick="type_key(';:')" /> - <input type="button" id="quote" value="'" onclick="type_key('\\x27\\x22')" /> - <input type="button" value="Enter" onclick="type_key('\\n\\n')" /> - <br> - <input type="button" id="ShiftLock" value="Caps Lock" onclick="key_shiftlock()" /> - <input type="button" id="Shift" value="Shift" onclick="key_shift()" /> - <input type="button" value="Z" onclick="type_key('zZ\\x1A')" /> - <input type="button" value="X" onclick="type_key('xX\\x18')" /> - <input type="button" value="C" onclick="type_key('cC\\x03')" /> - <input type="button" value="V" onclick="type_key('vV\\x16')" /> - <input type="button" value="B" onclick="type_key('bB\\x02')" /> - <input type="button" value="N" onclick="type_key('nN\\x0E')" /> - <input type="button" value="M" onclick="type_key('mM\\x0D')" /> - <input type="button" value=", <" onclick="type_key(',<')" /> - <input type="button" value=". >" onclick="type_key('.>')" /> - <input type="button" value="/ ?" onclick="type_key('/?')" /> - <input type="button" id="Shift2" value="Shift" onclick="key_shift()" /> - <input type="button" id="Ctrl2" value="Ctrl" onclick="key_ctrl()" /> - <br> - <input type="button" value=" FINAL FRONTIER " onclick="type_key(' ')" /> -</td> -</tr> -</table> -</form> -</body> -</html> -""" - -LOGIN_HTML="""<html> -<head> -<title>Shell Login</title> -<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> -<style type=text/css> -a {color: #9f9; text-decoration: none} -a:hover {color: #0f0} -hr {color: #0f0} -html,body,textarea,input,form -{ -font-family: "Courier New", Courier, mono; -font-size: 8pt; -color: #0c0; -background-color: #020; -margin:3; -padding:0; -border:0; -} -input { background-color: #010; } -input,textarea { -border-width:1; -border-style:solid; -border-color:#0c0; -padding:3; -margin:3; -} -</style> -<script language="JavaScript"> -function init () -{ - document.login_form["username"].focus(); -} -</script> -</head> -<body onload="init()"> -<form name="login_form" method="POST"> -<input name="start_server" value="1" type="hidden"> -<input name="sid" value="%(SID)s" type="hidden"> -username: <input name="username" type="text" size="30"><br> -password: <input name="password" type="password" size="30"><br> -<input name="submit" type="submit" value="enter"> -</form> -<br> -</body> -</html> -""" - -if __name__ == "__main__": - try: - main() - except Exception as e: - print(str(e)) - tb_dump = traceback.format_exc() - print(str(tb_dump)) - |