#!/usr/bin/env python3 import sys import os import pty import threading import empty import thr import cmd_ut import yaml_ut import dbg sec = 1.5 def b_to_s( b ): try: s = b.decode() except: return None return s def key_ev( s ): DIR = os.path.dirname( __file__ ) cmd = 'echo {} | {}/key_ev.py'.format( s, DIR ) cmd_ut.call( cmd ) 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 buf_new(): e = empty.new() e.bf = '' e.tmrs = [] def put( s ): if s.endswith( '\n' ): e.bf = '' return e.bf += s s = dic.get( e.bf ) if s: tmr = threading.Timer( sec, key_ev, ( s, ) ) tmr.start() e.tmrs.append( tmr ) def key_in( s ): if e.bf.endswith( ' password: ' ): dic.put( e.bf, s ) def tmr_cancel(): while e.tmrs: tmr = e.tmrs.pop( 0 ) tmr.cancel() def read( fd ): b = os.read( fd, 1024 ) s = b_to_s( b ) if s: put( s ) return b 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 def read( fd ): b = os.read( fd, 1024 ) buf.tmr_cancel() s = b_to_s( b ) if s: put( s ) return b return empty.add( e, locals() ) ibuf = ibuf_new() argv = sys.argv[ 1 : ] if not argv: argv = [ 'bash' ] pty.spawn( argv, buf.read, ibuf.read ) # EOF