#!/usr/bin/env python3 import sys import os import pty import termios import struct import fcntl import empty import yaml_ut import dbg sec = 1.5 argv = sys.argv[ 1 : ] pw_msgs = [ ' password: ' ] k = '-pw_msg=' for i in range( len( argv ) ): if argv[ i ].startswith( k ): s = argv.pop( i ) pw_msgs.append( s[ len( k ) : ] ) def b_to_s( b ): try: s = b.decode() except: return None return s def dic_new(): d = {} path = os.path.expandvars( "$HOME/.ezpass" ) if os.path.exists( path ): d = yaml_ut.load_fn( path, {} ) def save(): yaml_ut.save( d, path ) def get( k ): return d.get( k ) def put( k, v ): if k in d: return d[ k ] = v save() return empty.new( locals() ) dic = dic_new() def get_wsz( fd ): pfmt = 'HHHH' wsz = struct.pack( pfmt, 0, 0, 0, 0 ) wsz = fcntl.ioctl( fd, termios.TIOCGWINSZ, wsz ) ( rows, cols, xpix, ypix ) = struct.unpack( pfmt, wsz ) return ( cols, rows ) def set_wsz( fd, cols, rows ): pfmt = 'HHHH' wsz = struct.pack( pfmt, rows, cols, 0, 0 ) fcntl.ioctl( fd, termios.TIOCSWINSZ, wsz ) def buf_new(): e = empty.new() e.bf = '' e.wsz=None def put( s ): if s.endswith( '\n' ): e.bf = '' return e.bf += s def key_in( s ): for pw_msg in pw_msgs: if e.bf.endswith( pw_msg ): dic.put( e.bf, s ) break def get(): return e.bf def read( fd ): if e.wsz is None: set_sz( fd ) b = os.read( fd, 1024 ) s = b_to_s( b ) if s: put( s ) return b def set_sz( fd ): ( cols, rows ) = e.wsz = get_wsz( sys.stdout.fileno() ) set_wsz( fd, cols, rows ) return empty.add( e, locals() ) buf = buf_new() def ibuf_new(): e = empty.new() e.bf = '' def put( s ): if s == '\r': buf.key_in( e.bf ) e.bf = '' return e.bf += s if e.bf == '\t': return dic.get( buf.get() ) return None def read( fd ): b = os.read( fd, 1024 ) s = b_to_s( b ) if s: s = put( s ) if s: s += '\r' b = s.encode() return b return empty.add( e, locals() ) ibuf = ibuf_new() if not argv: argv = [ 'bash' ] pty.spawn( argv, buf.read, ibuf.read ) # EOF