Skip to content
Find file
Fetching contributors…
Cannot retrieve contributors at this time
198 lines (166 sloc) 4.44 KB
#! perl
use IO::Pty::Easy;
sub on_init {
my ($self) = @_;
my $hotkey = $self->{argv}[0]
|| $self->x_resource ("pwsafe")
|| "M-w";
$self->parse_keysym ($hotkey, "perl:pwsafe:start")
or warn "unable to register '$hotkey' as pwsafe start hotkey\n";
return;
}
sub on_user_command {
my ($self, $cmd) = @_;
$self->enter if $cmd eq 'pwsafe:start';
return;
}
sub enter {
my ($self) = @_;
return if $self->displaying_msg || $self->displaying_prompt;
$self->enable(
key_press => \&key_press,
);
#eval {
$self->do_password;
#};
#if ($@) {
#$self->timed_message($@);
#$self->leave;
#}
}
sub leave {
my ($self) = @_;
delete $self->{overlay};
delete $self->{prompt};
delete $self->{state};
$self->disable("key_press");
}
sub msg {
my ($self, $msg) = @_;
delete $self->{timed_overlay};
$self->{overlay} = $self->overlay (0, -2, $self->ncol, 1, urxvt::OVERLAY_RSTYLE, 0);
$self->{overlay}->set (0, 0, $self->special_encode ($msg));
}
sub timed_msg {
my ($self, $msg) = @_;
delete $self->{overlay};
$self->{timed_overlay} = $self->overlay (0, -2, $self->ncol, 1, urxvt::OVERLAY_RSTYLE, 0);
$self->{timed_overlay}->set (0, 0, $self->special_encode ($msg));
$self->{timed_overlay_timer} = urxvt::timer->new->after(1)->cb(sub {
delete $self->{timed_overlay};
});
}
sub displaying_msg {
my ($self) = @_;
return defined $self->{overlay};
}
sub prompt {
my ($self, $msg, $hide, $next) = @_;
$self->{state} = 'prompt';
$self->{prompt_hide} = $hide;
$self->{prompt_msg} = $msg;
$self->{prompt_next} = $next;
$self->{prompt_buffer} = '';
$self->prompt_redisplay;
}
sub prompt_redisplay {
my ($self) = @_;
my $buf = $self->{prompt_buffer};
$buf = '' if $self->{prompt_hide};
my $msg = $self->{prompt_msg} . $buf. "";
$self->{prompt} = $self->overlay(0, -1, $self->ncol, 1, urxvt::OVERLAY_RSTYLE, 0);
$self->{prompt}->set(0, 0, $self->special_encode ($msg));
}
sub displaying_prompt {
my ($self) = @_;
return $self->{state} eq 'prompt';
}
sub prompt_handle {
my ($self, $string) = @_;
$self->{prompt_buffer} .= $string;
$self->prompt_redisplay;
}
sub prompt_delete {
my ($self) = @_;
substr $self->{prompt_buffer}, -1, 1, "";
$self->prompt_redisplay;
}
sub prompt_finish {
my ($self) = @_;
delete $self->{prompt};
delete $self->{state};
my $next = delete $self->{prompt_next};
my $buf = delete $self->{prompt_buffer};
$next->($buf);
return;
}
sub do_password {
my ($self) = @_;
$self->prompt('Password database password: ', 1, sub {
my $pass = shift;
if ($pass) {
$self->which_password($pass);
}
else {
$self->timed_msg('Aborted.');
$self->leave;
return;
}
});
}
sub which_password {
my $self = shift;
my $pass = shift;
$self->prompt('Password to insert: ', 0, sub {
my $passname = shift;
my $pty = IO::Pty::Easy->new;
$pty->spawn("pwsafe -pE $passname");
my $read;
while (1) {
$read = $pty->read(0);
last if $read =~ /passphrase for/;
}
$pty->write("$pass\n");
my $password;
while (1) {
$password = $pty->read(0);
last if $password =~ s/password for.*?: //;
if ($password =~ /incorrect/) {
$self->do_password;
return;
}
if ($password =~ /(?:No|More than one) matching entr/) {
$self->which_password($pass);
return;
}
}
if ($password) {
$self->tt_write($password);
$self->leave;
}
else {
$self->msg("Unknown password $passname");
$self->which_password($pass);
}
});
}
sub key_press {
my ($self, $event, $keysym, $string) = @_;
delete $self->{manpage_overlay};
if ($keysym == 0xff1b || $string =~ /\cc/) { # escape or ^C
$self->timed_msg('Aborted.');
$self->leave;
}
if ($self->{state} eq 'prompt'){
if ($keysym == 0xff0d || $keysym == 0xff8d) { # enter
$self->prompt_finish;
}
elsif ($keysym == 0xff08) { # backspace
$self->prompt_delete;
}
else {
$self->prompt_handle($string);
}
}
return 1;
}
Something went wrong with that request. Please try again.