blob: fd4a9aa61235148bbd45597b362652bcd054f9e6 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
#!/usr/bin/env perl
use strict;
use warnings;
my $PASS = '/usr/bin/pass';
my $cmd = $ARGV[0];
if ($cmd && $cmd eq 'search') {
shift @ARGV;
chdir "$ENV{HOME}/.password-store"
or die "password store not initialized";
require Path::Class;
my $pat_str = pop @ARGV;
my $pattern = qr/$pat_str/;
my $username = grep { $_ eq '-u' } @ARGV;
@ARGV = grep { $_ ne '-u' } @ARGV;
my $clipboard = grep { $_ eq '-c' || $_ eq '--clip' } @ARGV;
my @found = Path::Class::Dir->new('.')->traverse(sub {
my ($file, $c) = @_;
return if $file eq '.git';
return (
$c->(),
((-f $file && $file =~ s/\.gpg$// && $file =~ $pattern)
? ($file)
: ()),
);
});
if (@found < 1) {
die "No passwords found matching '$pat_str'\n";
}
elsif (@found > 1) {
die "Ambiguous pattern '$pat_str': could match any of @found\n";
}
else {
if (my $pass = `$PASS show '$found[0]'`) {
if ($username) {
if ($found[0] =~ m{^[^/]*/[^/]*/([^/]*)$}) {
my $user = $1;
if ($clipboard) {
clip($user);
}
else {
print "$user\n";
}
}
else {
die "$found[0] has no username";
}
}
if ($clipboard) {
$pass =~ s/\n.*//s;
clip($pass);
}
else {
print $pass;
}
}
}
}
else {
exec { $PASS } $PASS, @ARGV
}
sub clip {
my ($text) = @_;
my @pids;
for my $selection (qw(primary clipboard)) {
my $pid = fork;
if (!$pid) {
open my $fh, '|-', "timeout 1m xclip -loops 1 -quiet -selection $selection 2> /dev/null"
or die "couldn't run xclip";
$fh->write("$text\n");
$fh->close;
exit;
}
push @pids, $pid;
}
waitpid($_, 0) for @pids;
}
|